summaryrefslogtreecommitdiff
Unidiff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--library/backend/vcc.y22
-rw-r--r--library/backend/vcc_yacc.cpp139
-rw-r--r--library/backend/vobject.cpp273
-rw-r--r--library/backend/vobject_p.h31
4 files changed, 251 insertions, 214 deletions
diff --git a/library/backend/vcc.y b/library/backend/vcc.y
index 6781312..94a8fea 100644
--- a/library/backend/vcc.y
+++ b/library/backend/vcc.y
@@ -29,193 +29,193 @@ DAMAGE.
29 29
30EACH LICENSOR SPECIFICALLY DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, 30EACH LICENSOR SPECIFICALLY DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED,
31INCLUDING BUT NOT LIMITED TO ANY WARRANTY OF NONINFRINGEMENT OR THE 31INCLUDING BUT NOT LIMITED TO ANY WARRANTY OF NONINFRINGEMENT OR THE
32IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 32IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
33PURPOSE. 33PURPOSE.
34 34
35The software is provided with RESTRICTED RIGHTS. Use, duplication, or 35The software is provided with RESTRICTED RIGHTS. Use, duplication, or
36disclosure by the government are subject to restrictions set forth in 36disclosure by the government are subject to restrictions set forth in
37DFARS 252.227-7013 or 48 CFR 52.227-19, as applicable. 37DFARS 252.227-7013 or 48 CFR 52.227-19, as applicable.
38 38
39***************************************************************************/ 39***************************************************************************/
40 40
41/* 41/*
42 * src: vcc.c 42 * src: vcc.c
43 * doc: Parser for vCard and vCalendar. Note that this code is 43 * doc: Parser for vCard and vCalendar. Note that this code is
44 * generated by a yacc parser generator. Generally it should not 44 * generated by a yacc parser generator. Generally it should not
45 * be edited by hand. The real source is vcc.y. The #line directives 45 * be edited by hand. The real source is vcc.y. The #line directives
46 * can be commented out here to make it easier to trace through 46 * can be commented out here to make it easier to trace through
47 * in a debugger. However, if a bug is found it should 47 * in a debugger. However, if a bug is found it should
48 * be fixed in vcc.y and this file regenerated. 48 * be fixed in vcc.y and this file regenerated.
49 */ 49 */
50 50
51 51
52/* debugging utilities */ 52/* debugging utilities */
53#if __DEBUG 53#if __DEBUG
54#define DBG_(x) printf x 54#define DBG_(x) printf x
55#else 55#else
56#define DBG_(x) 56#define DBG_(x)
57#endif 57#endif
58 58
59/**** External Functions ****/ 59/**** External Functions ****/
60 60
61/* assign local name to parser variables and functions so that 61/* assign local name to parser variables and functions so that
62 we can use more than one yacc based parser. 62 we can use more than one yacc based parser.
63*/ 63*/
64 64
65#if 0 65#if 0
66#define yyparse mime_parse 66#define yyparse mime_parse
67#define yylex mime_lex 67#define yylex mime_lex
68#define yyerror mime_error 68#define yyerror mime_error
69#define yychar mime_char 69#define yychar mime_char
70/* #define p_yyval p_mime_val */ 70/* #define p_yyval p_mime_val */
71#undef yyval 71#undef yyval
72#define yyval mime_yyval 72#define yyval mime_yyval
73/* #define p_yylval p_mime_lval */ 73/* #define p_yylval p_mime_lval */
74#undef yylval 74#undef yylval
75#define yylval mime_yylval 75#define yylval mime_yylval
76#define yydebug mime_debug 76#define yydebug mime_debug
77#define yynerrs mime_nerrs 77#define yynerrs mime_nerrs
78#define yyerrflag mime_errflag 78#define yyerrflag mime_errflag
79#define yyss mime_ss 79#define yyss mime_ss
80#define yyssp mime_ssp 80#define yyssp mime_ssp
81#define yyvs mime_vs 81#define yyvs mime_vs
82#define yyvsp mime_vsp 82#define yyvsp mime_vsp
83#define yylhs mime_lhs 83#define yylhs mime_lhs
84#define yylen mime_len 84#define yylen mime_len
85#define yydefred mime_defred 85#define yydefred mime_defred
86#define yydgoto mime_dgoto 86#define yydgoto mime_dgoto
87#define yysindex mime_sindex 87#define yysindex mime_sindex
88#define yyrindex mime_rindex 88#define yyrindex mime_rindex
89#define yygindex mime_gindex 89#define yygindex mime_gindex
90#define yytable mime_table 90#define yytable mime_table
91#define yycheck mime_check 91#define yycheck mime_check
92#define yyname mime_name 92#define yyname mime_name
93#define yyrule mime_rule 93#define yyrule mime_rule
94#ifdef YYPREFIX 94#ifdef YYPREFIX
95#undef YYPREFIX 95#undef YYPREFIX
96#endif 96#endif
97#define YYPREFIX "mime_" 97#define YYPREFIX "mime_"
98#endif 98#endif
99 99
100 100
101#ifndef _NO_LINE_FOLDING 101#ifndef _NO_LINE_FOLDING
102#define _SUPPORT_LINE_FOLDING 1 102#define _SUPPORT_LINE_FOLDING 1
103#endif 103#endif
104 104
105/* undef below if compile with MFC */ 105/* undef below if compile with MFC */
106/* #define INCLUDEMFC 1 */ 106/* #define INCLUDEMFC 1 */
107 107
108#if defined(WIN32) || defined(_WIN32) 108#if defined(WIN32) || defined(_WIN32)
109#ifdef INCLUDEMFC 109#ifdef INCLUDEMFC
110#include <afx.h> 110#include <afx.h>
111#endif 111#endif
112#endif 112#endif
113 113
114#include <string.h> 114#include <string.h>
115#ifndef __MWERKS__ 115#ifndef __MWERKS__
116#include <stdlib.h> 116#include <stdlib.h>
117#endif 117#endif
118#include <stdio.h> 118#include <stdio.h>
119#include <stdlib.h> 119#include <stdlib.h>
120#include <ctype.h> 120#include <ctype.h>
121 121
122//#ifdef PALMTOPCENTER 122//#ifdef PALMTOPCENTER
123//#include <qpe/vobject_p.h> 123//#include <qpe/vobject_p.h>
124//#else 124//#else
125#include <qtopia/private/vobject_p.h> 125#include "vobject_p.h"
126//#endif 126//#endif
127 127
128/**** Types, Constants ****/ 128/**** Types, Constants ****/
129 129
130 #define YYDEBUG 0/* 1 to compile in some debugging code */ 130 #define YYDEBUG 0/* 1 to compile in some debugging code */
131 #define MAXTOKEN 256/* maximum token (line) length */ 131 #define MAXTOKEN 256/* maximum token (line) length */
132 #define YYSTACKSIZE 100// ~unref ? 132 #define YYSTACKSIZE 100// ~unref ?
133 #define MAXLEVEL 10/* max # of nested objects parseable */ 133 #define MAXLEVEL 10/* max # of nested objects parseable */
134 /* (includes outermost) */ 134 /* (includes outermost) */
135 135
136 136
137/**** Global Variables ****/ 137/**** Global Variables ****/
138int mime_lineNum, mime_numErrors; /* yyerror() can use these */ 138int mime_lineNum, mime_numErrors; /* yyerror() can use these */
139static VObject* vObjList; 139static VObject* vObjList;
140static VObject *curProp; 140static VObject *curProp;
141static VObject *curObj; 141static VObject *curObj;
142static VObject* ObjStack[MAXLEVEL]; 142static VObject* ObjStack[MAXLEVEL];
143static int ObjStackTop; 143static int ObjStackTop;
144 144
145 145
146/* A helpful utility for the rest of the app. */ 146/* A helpful utility for the rest of the app. */
147#if __CPLUSPLUS__ 147#if __CPLUSPLUS__
148extern "C" { 148extern "C" {
149#endif 149#endif
150 150
151 extern void yyerror(char *s); 151 extern void yyerror(char *s);
152 152
153#if __CPLUSPLUS__ 153#if __CPLUSPLUS__
154 }; 154 };
155#endif 155#endif
156 156
157int yyparse(); 157int yyparse();
158 158
159enum LexMode { 159enum LexMode {
160 L_NORMAL, 160 L_NORMAL,
161 L_VCARD, 161 L_VCARD,
162 L_VCAL, 162 L_VCAL,
163 L_VEVENT, 163 L_VEVENT,
164 L_VTODO, 164 L_VTODO,
165 L_VALUES, 165 L_VALUES,
166 L_BASE64, 166 L_BASE64,
167 L_QUOTED_PRINTABLE 167 L_QUOTED_PRINTABLE
168 }; 168 };
169 169
170/**** Private Forward Declarations ****/ 170/**** Private Forward Declarations ****/
171static int pushVObject(const char *prop); 171static int pushVObject(const char *prop);
172static VObject* popVObject(); 172static VObject* popVObject();
173static void lexPopMode(int top); 173static void lexPopMode(int top);
174static int lexWithinMode(enum LexMode mode); 174static int lexWithinMode(enum LexMode mode);
175static void lexPushMode(enum LexMode mode); 175static void lexPushMode(enum LexMode mode);
176static void enterProps(const char *s); 176static void enterProps(const char *s);
177static void enterAttr(const char *s1, const char *s2); 177static void enterAttr(const char *s1, const char *s2);
178static void enterValues(const char *value); 178static void enterValues(const char *value);
179#define mime_error yyerror 179#define mime_error yyerror
180void mime_error(char *s); 180void mime_error(char *s);
181void mime_error_(char *s); 181void mime_error_(char *s);
182 182
183%} 183%}
184 184
185/***************************************************************************/ 185/***************************************************************************/
186/*** The grammar ****/ 186/*** The grammar ****/
187/***************************************************************************/ 187/***************************************************************************/
188 188
189%union { 189%union {
190 char *str; 190 char *str;
191 VObject *vobj; 191 VObject *vobj;
192 } 192 }
193 193
194%token 194%token
195 EQ COLON DOT SEMICOLON SPACE HTAB LINESEP NEWLINE 195 EQ COLON DOT SEMICOLON SPACE HTAB LINESEP NEWLINE
196 BEGIN_VCARD END_VCARD BEGIN_VCAL END_VCAL 196 BEGIN_VCARD END_VCARD BEGIN_VCAL END_VCAL
197 BEGIN_VEVENT END_VEVENT BEGIN_VTODO END_VTODO 197 BEGIN_VEVENT END_VEVENT BEGIN_VTODO END_VTODO
198 ID 198 ID
199 199
200/* 200/*
201 * NEWLINE is the token that would occur outside a vCard, 201 * NEWLINE is the token that would occur outside a vCard,
202 * while LINESEP is the token that would occur inside a vCard. 202 * while LINESEP is the token that would occur inside a vCard.
203 */ 203 */
204 204
205%token <str> 205%token <str>
206 STRING ID 206 STRING ID
207 207
208%type <str> name value 208%type <str> name value
209 209
210%type <vobj> vcard vcal vobject 210%type <vobj> vcard vcal vobject
211 211
212%start mime 212%start mime
213 213
214%% 214%%
215 215
216 216
217mime: vobjects 217mime: vobjects
218 ; 218 ;
219 219
220vobjects: vobjects vobject 220vobjects: vobjects vobject
221 { addList(&vObjList, $2); curObj = 0; } 221 { addList(&vObjList, $2); curObj = 0; }
@@ -630,202 +630,208 @@ static void lexSkipWhite() {
630static char* lexGetWord() { 630static char* lexGetWord() {
631 int c; 631 int c;
632 lexSkipWhite(); 632 lexSkipWhite();
633 lexClearToken(); 633 lexClearToken();
634 c = lexLookahead(); 634 c = lexLookahead();
635 while (c != EOF && !strchr("\t\n ;:=",c)) { 635 while (c != EOF && !strchr("\t\n ;:=",c)) {
636 lexAppendc(c); 636 lexAppendc(c);
637 lexSkipLookahead(); 637 lexSkipLookahead();
638 c = lexLookahead(); 638 c = lexLookahead();
639 } 639 }
640 lexAppendc(0); 640 lexAppendc(0);
641 return lexStr(); 641 return lexStr();
642 } 642 }
643 643
644static void lexPushLookaheadc(int c) { 644static void lexPushLookaheadc(int c) {
645 int putptr; 645 int putptr;
646 /* can't putback EOF, because it never leaves lookahead buffer */ 646 /* can't putback EOF, because it never leaves lookahead buffer */
647 if (c == EOF) return; 647 if (c == EOF) return;
648 putptr = (int)lexBuf.getPtr - 1; 648 putptr = (int)lexBuf.getPtr - 1;
649 if (putptr < 0) putptr += MAX_LEX_LOOKAHEAD; 649 if (putptr < 0) putptr += MAX_LEX_LOOKAHEAD;
650 lexBuf.getPtr = putptr; 650 lexBuf.getPtr = putptr;
651 lexBuf.buf[putptr] = c; 651 lexBuf.buf[putptr] = c;
652 lexBuf.len += 1; 652 lexBuf.len += 1;
653 } 653 }
654 654
655static char* lexLookaheadWord() { 655static char* lexLookaheadWord() {
656 /* this function can lookahead word with max size of MAX_LEX_LOOKAHEAD_0 656 /* this function can lookahead word with max size of MAX_LEX_LOOKAHEAD_0
657 / and thing bigger than that will stop the lookahead and return 0; 657 / and thing bigger than that will stop the lookahead and return 0;
658 / leading white spaces are not recoverable. 658 / leading white spaces are not recoverable.
659 */ 659 */
660 int c; 660 int c;
661 int len = 0; 661 int len = 0;
662 int curgetptr = 0; 662 int curgetptr = 0;
663 lexSkipWhite(); 663 lexSkipWhite();
664 lexClearToken(); 664 lexClearToken();
665 curgetptr = (int)lexBuf.getPtr;// remember! 665 curgetptr = (int)lexBuf.getPtr;// remember!
666 while (len < (MAX_LEX_LOOKAHEAD_0)) { 666 while (len < (MAX_LEX_LOOKAHEAD_0)) {
667 c = lexGetc(); 667 c = lexGetc();
668 len++; 668 len++;
669 if (c == EOF || strchr("\t\n ;:=", c)) { 669 if (c == EOF || strchr("\t\n ;:=", c)) {
670 lexAppendc(0); 670 lexAppendc(0);
671 /* restore lookahead buf. */ 671 /* restore lookahead buf. */
672 lexBuf.len += len; 672 lexBuf.len += len;
673 lexBuf.getPtr = curgetptr; 673 lexBuf.getPtr = curgetptr;
674 return lexStr(); 674 return lexStr();
675 } 675 }
676 else 676 else
677 lexAppendc(c); 677 lexAppendc(c);
678 } 678 }
679 lexBuf.len += len;/* char that has been moved to lookahead buffer */ 679 lexBuf.len += len;/* char that has been moved to lookahead buffer */
680 lexBuf.getPtr = curgetptr; 680 lexBuf.getPtr = curgetptr;
681 return 0; 681 return 0;
682 } 682 }
683 683
684#ifdef _SUPPORT_LINE_FOLDING 684#ifdef _SUPPORT_LINE_FOLDING
685static void handleMoreRFC822LineBreak(int c) { 685static void handleMoreRFC822LineBreak(int c) {
686 /* suport RFC 822 line break in cases like 686 /* suport RFC 822 line break in cases like
687 *ADR: foo; 687 *ADR: foo;
688 * morefoo; 688 * morefoo;
689 * more foo; 689 * more foo;
690 */ 690 */
691 if (c == ';') { 691 if (c == ';') {
692 int a; 692 int a;
693 lexSkipLookahead(); 693 lexSkipLookahead();
694 /* skip white spaces */ 694 /* skip white spaces */
695 a = lexLookahead(); 695 a = lexLookahead();
696 while (a == ' ' || a == '\t') { 696 while (a == ' ' || a == '\t') {
697 lexSkipLookahead(); 697 lexSkipLookahead();
698 a = lexLookahead(); 698 a = lexLookahead();
699 } 699 }
700 if (a == '\n') { 700 if (a == '\n') {
701 lexSkipLookahead(); 701 lexSkipLookahead();
702 a = lexLookahead(); 702 a = lexLookahead();
703 if (a == ' ' || a == '\t') { 703 if (a == ' ' || a == '\t') {
704 /* continuation, throw away all the \n and spaces read so 704 /* continuation, throw away all the \n and spaces read so
705 * far 705 * far
706 */ 706 */
707 lexSkipWhite(); 707 lexSkipWhite();
708 lexPushLookaheadc(';'); 708 lexPushLookaheadc(';');
709 } 709 }
710 else { 710 else {
711 lexPushLookaheadc('\n'); 711 lexPushLookaheadc('\n');
712 lexPushLookaheadc(';'); 712 lexPushLookaheadc(';');
713 } 713 }
714 } 714 }
715 else { 715 else {
716 lexPushLookaheadc(';'); 716 lexPushLookaheadc(';');
717 } 717 }
718 } 718 }
719 } 719 }
720 720
721static char* lexGet1Value() { 721static char* lexGet1Value() {
722 int c; 722 int c;
723 lexSkipWhite(); 723 lexSkipWhite();
724 c = lexLookahead(); 724 c = lexLookahead();
725 lexClearToken(); 725 lexClearToken();
726 while (c != EOF && c != ';') { 726 while (c != EOF && (c != ';' || !fieldedProp)) {
727 if (c == '\\' ) { 727 if (c == '\\' ) {
728 int a; 728 int a;
729 lexSkipLookahead(); 729 lexSkipLookahead();
730 a = lexLookahead(); 730 a = lexLookahead();
731 if ( a != ';' ) { 731 if ( a == ';' ) {
732 lexAppendc('\\');
733 } else {
734 lexAppendc( ';' ); 732 lexAppendc( ';' );
735 lexSkipLookahead(); 733 lexSkipLookahead();
734 } else if ( a == '\n' ) {
735 lexAppendc( '\n' );
736 lexSkipLookahead();
737 } else if ( a == '\\' ) {
738 lexAppendc( '\\' );
739 lexSkipLookahead();
740 } else {
741 lexAppendc('\\');
736 } 742 }
737 } else if (c == '\n') { 743 } else if (c == '\n') {
738 int a; 744 int a;
739 lexSkipLookahead(); 745 lexSkipLookahead();
740 a = lexLookahead(); 746 a = lexLookahead();
741 if (a == ' ' || a == '\t') { 747 if (a == ' ' || a == '\t') {
742 lexAppendc(' '); 748 lexAppendc(' ');
743 lexSkipLookahead(); 749 lexSkipLookahead();
744 } 750 }
745 else { 751 else {
746 lexPushLookaheadc('\n'); 752 lexPushLookaheadc('\n');
747 break; 753 break;
748 } 754 }
749 } 755 }
750 else { 756 else {
751 lexAppendc(c); 757 lexAppendc(c);
752 lexSkipLookahead(); 758 lexSkipLookahead();
753 } 759 }
754 c = lexLookahead(); 760 c = lexLookahead();
755 } 761 }
756 lexAppendc(0); 762 lexAppendc(0);
757 handleMoreRFC822LineBreak(c); 763 handleMoreRFC822LineBreak(c);
758 return c==EOF?0:lexStr(); 764 return c==EOF?0:lexStr();
759 } 765 }
760#endif 766#endif
761 767
762static int match_begin_name(int end) { 768static int match_begin_name(int end) {
763 char *n = lexLookaheadWord(); 769 char *n = lexLookaheadWord();
764 int token = ID; 770 int token = ID;
765 if (n) { 771 if (n) {
766 if (!qstricmp(n,"vcard")) token = end?END_VCARD:BEGIN_VCARD; 772 if (!qstricmp(n,"vcard")) token = end?END_VCARD:BEGIN_VCARD;
767 else if (!qstricmp(n,"vcalendar")) token = end?END_VCAL:BEGIN_VCAL; 773 else if (!qstricmp(n,"vcalendar")) token = end?END_VCAL:BEGIN_VCAL;
768 else if (!qstricmp(n,"vevent")) token = end?END_VEVENT:BEGIN_VEVENT; 774 else if (!qstricmp(n,"vevent")) token = end?END_VEVENT:BEGIN_VEVENT;
769 else if (!qstricmp(n,"vtodo")) token = end?END_VTODO:BEGIN_VTODO; 775 else if (!qstricmp(n,"vtodo")) token = end?END_VTODO:BEGIN_VTODO;
770 deleteStr(n); 776 deleteStr(n);
771 return token; 777 return token;
772 } 778 }
773 return 0; 779 return 0;
774 } 780 }
775 781
776 782
777#ifdef INCLUDEMFC 783#ifdef INCLUDEMFC
778void initLex(const char *inputstring, unsigned long inputlen, CFile *inputfile) 784void initLex(const char *inputstring, unsigned long inputlen, CFile *inputfile)
779#else 785#else
780void initLex(const char *inputstring, unsigned long inputlen, FILE *inputfile) 786void initLex(const char *inputstring, unsigned long inputlen, FILE *inputfile)
781#endif 787#endif
782 { 788 {
783 // initialize lex mode stack 789 // initialize lex mode stack
784 lexBuf.lexModeStack[lexBuf.lexModeStackTop=0] = L_NORMAL; 790 lexBuf.lexModeStack[lexBuf.lexModeStackTop=0] = L_NORMAL;
785 791
786 // iniatialize lex buffer. 792 // iniatialize lex buffer.
787 lexBuf.inputString = (char*) inputstring; 793 lexBuf.inputString = (char*) inputstring;
788 lexBuf.inputLen = inputlen; 794 lexBuf.inputLen = inputlen;
789 lexBuf.curPos = 0; 795 lexBuf.curPos = 0;
790 lexBuf.inputFile = inputfile; 796 lexBuf.inputFile = inputfile;
791 797
792 lexBuf.len = 0; 798 lexBuf.len = 0;
793 lexBuf.getPtr = 0; 799 lexBuf.getPtr = 0;
794 800
795 lexBuf.maxToken = MAXTOKEN; 801 lexBuf.maxToken = MAXTOKEN;
796 lexBuf.strs = (char*)malloc(MAXTOKEN); 802 lexBuf.strs = (char*)malloc(MAXTOKEN);
797 lexBuf.strsLen = 0; 803 lexBuf.strsLen = 0;
798 804
799 } 805 }
800 806
801static void finiLex() { 807static void finiLex() {
802 free(lexBuf.strs); 808 free(lexBuf.strs);
803 } 809 }
804 810
805 811
806/*-----------------------------------*/ 812/*-----------------------------------*/
807/* This parses and converts the base64 format for binary encoding into 813/* This parses and converts the base64 format for binary encoding into
808 * a decoded buffer (allocated with new). See RFC 1521. 814 * a decoded buffer (allocated with new). See RFC 1521.
809 */ 815 */
810static char * lexGetDataFromBase64() 816static char * lexGetDataFromBase64()
811 { 817 {
812 unsigned long bytesLen = 0, bytesMax = 0; 818 unsigned long bytesLen = 0, bytesMax = 0;
813 int quadIx = 0, pad = 0; 819 int quadIx = 0, pad = 0;
814 unsigned long trip = 0; 820 unsigned long trip = 0;
815 unsigned char b; 821 unsigned char b;
816 int c; 822 int c;
817 unsigned char *bytes = NULL; 823 unsigned char *bytes = NULL;
818 unsigned char *oldBytes = NULL; 824 unsigned char *oldBytes = NULL;
819 825
820 DBG_(("db: lexGetDataFromBase64\n")); 826 DBG_(("db: lexGetDataFromBase64\n"));
821 while (1) { 827 while (1) {
822 c = lexGetc(); 828 c = lexGetc();
823 if (c == '\n') { 829 if (c == '\n') {
824 ++mime_lineNum; 830 ++mime_lineNum;
825 if (lexLookahead() == '\n') { 831 if (lexLookahead() == '\n') {
826 /* a '\n' character by itself means end of data */ 832 /* a '\n' character by itself means end of data */
827 break; 833 break;
828 } 834 }
829 else continue; /* ignore '\n' */ 835 else continue; /* ignore '\n' */
830 } 836 }
831 else { 837 else {
@@ -868,291 +874,295 @@ static char * lexGetDataFromBase64()
868 int i; 874 int i;
869 for (i = 0; i < 3; i++) { 875 for (i = 0; i < 3; i++) {
870 outBytes[2-i] = (unsigned char)(trip & 0xFF); 876 outBytes[2-i] = (unsigned char)(trip & 0xFF);
871 trip >>= 8; 877 trip >>= 8;
872 } 878 }
873 numOut = 3 - pad; 879 numOut = 3 - pad;
874 if (bytesLen + numOut > bytesMax) { 880 if (bytesLen + numOut > bytesMax) {
875 if (!bytes) { 881 if (!bytes) {
876 bytesMax = 1024; 882 bytesMax = 1024;
877 bytes = (unsigned char*)malloc((size_t)bytesMax); 883 bytes = (unsigned char*)malloc((size_t)bytesMax);
878 } 884 }
879 else { 885 else {
880 bytesMax <<= 2; 886 bytesMax <<= 2;
881 oldBytes = bytes; 887 oldBytes = bytes;
882 bytes = (unsigned char*)realloc(bytes,(size_t)bytesMax); 888 bytes = (unsigned char*)realloc(bytes,(size_t)bytesMax);
883 } 889 }
884 if (bytes == 0) { 890 if (bytes == 0) {
885 mime_error("out of memory while processing BASE64 data\n"); 891 mime_error("out of memory while processing BASE64 data\n");
886 } 892 }
887 } 893 }
888 if (bytes) { 894 if (bytes) {
889 memcpy(bytes + bytesLen, outBytes, numOut); 895 memcpy(bytes + bytesLen, outBytes, numOut);
890 bytesLen += numOut; 896 bytesLen += numOut;
891 } 897 }
892 trip = 0; 898 trip = 0;
893 quadIx = 0; 899 quadIx = 0;
894 } 900 }
895 } 901 }
896 } /* while */ 902 } /* while */
897 DBG_(("db: bytesLen = %d\n", bytesLen)); 903 DBG_(("db: bytesLen = %d\n", bytesLen));
898 /* kludge: all this won't be necessary if we have tree form 904 /* kludge: all this won't be necessary if we have tree form
899 representation */ 905 representation */
900 if (bytes) { 906 if (bytes) {
901 setValueWithSize(curProp,bytes,(unsigned int)bytesLen); 907 setValueWithSize(curProp,bytes,(unsigned int)bytesLen);
902 free(bytes); 908 free(bytes);
903 } 909 }
904 else if (oldBytes) { 910 else if (oldBytes) {
905 setValueWithSize(curProp,oldBytes,(unsigned int)bytesLen); 911 setValueWithSize(curProp,oldBytes,(unsigned int)bytesLen);
906 free(oldBytes); 912 free(oldBytes);
907 } 913 }
908 return 0; 914 return 0;
909 } 915 }
910 916
911static int match_begin_end_name(int end) { 917static int match_begin_end_name(int end) {
912 int token; 918 int token;
913 lexSkipWhite(); 919 lexSkipWhite();
914 if (lexLookahead() != ':') return ID; 920 if (lexLookahead() != ':') return ID;
915 lexSkipLookahead(); 921 lexSkipLookahead();
916 lexSkipWhite(); 922 lexSkipWhite();
917 token = match_begin_name(end); 923 token = match_begin_name(end);
918 if (token == ID) { 924 if (token == ID) {
919 lexPushLookaheadc(':'); 925 lexPushLookaheadc(':');
920 DBG_(("db: ID '%s'\n", yylval.str)); 926 DBG_(("db: ID '%s'\n", yylval.str));
921 return ID; 927 return ID;
922 } 928 }
923 else if (token != 0) { 929 else if (token != 0) {
924 lexSkipLookaheadWord(); 930 lexSkipLookaheadWord();
925 deleteStr(yylval.str); 931 deleteStr(yylval.str);
926 DBG_(("db: begin/end %d\n", token)); 932 DBG_(("db: begin/end %d\n", token));
927 return token; 933 return token;
928 } 934 }
929 return 0; 935 return 0;
930 } 936 }
931 937
932static char* lexGetQuotedPrintable() 938static char* lexGetQuotedPrintable()
933{ 939{
934 int c; 940 int c;
935 lexSkipWhite(); 941 lexSkipWhite();
936 c = lexLookahead(); 942 c = lexLookahead();
937 lexClearToken(); 943 lexClearToken();
938 944
939 while (c != EOF && c != ';') { 945 while (c != EOF && c != ';') {
940 if (c == '\n') { 946 if (c == '\n') {
941 // break, leave '\n' on remaining chars. 947 // break, leave '\n' on remaining chars.
942 break; 948 break;
943 } else if (c == '=') { 949 } else if (c == '=') {
944 int cur = 0; 950 int cur = 0;
945 int next; 951 int next;
946 952
947 lexSkipLookahead(); // skip '=' 953 lexSkipLookahead(); // skip '='
948 next = lexLookahead(); 954 next = lexLookahead();
949 955
950 if (next == '\n') { 956 if (next == '\n') {
951 // skip and only skip the \n 957 // skip and only skip the \n
952 lexSkipLookahead(); 958 lexSkipLookahead();
953 c = lexLookahead(); 959 c = lexLookahead();
954 ++mime_lineNum; // aid in error reporting 960 ++mime_lineNum; // aid in error reporting
955 continue; 961 continue;
956 } else if (next >= '0' && next <= '9') { 962 } else if (next >= '0' && next <= '9') {
957 cur = next - '0'; 963 cur = next - '0';
958 } else if (next >= 'A' && next <= 'F') { 964 } else if (next >= 'A' && next <= 'F') {
959 cur = next - 'A' + 10; 965 cur = next - 'A' + 10;
960 } else { 966 } else {
961 // we have been sent buggy stuff. doesn't matter 967 // we have been sent buggy stuff. doesn't matter
962 // what we do so long as we keep going. 968 // what we do so long as we keep going.
963 // should probably spit an error here 969 // should probably spit an error here
970 lexSkipLookahead();
964 c = lexLookahead(); 971 c = lexLookahead();
965 continue; 972 continue;
966 } 973 }
967 974
968 lexSkipLookahead(); // skip A-Z0-9 975 lexSkipLookahead(); // skip A-Z0-9
969 next = lexLookahead(); 976 next = lexLookahead();
970 977
971 cur = cur * 16; 978 cur = cur * 16;
972 // this time really just expecting 0-9A-F 979 // this time really just expecting 0-9A-F
973 if (next >= '0' && next <= '9') { 980 if (next >= '0' && next <= '9') {
974 cur += next - '0'; 981 cur += next - '0';
975 } else if (next >= 'A' && next <= 'F') { 982 } else if (next >= 'A' && next <= 'F') {
976 cur += next - 'A' + 10; 983 cur += next - 'A' + 10;
977 } else { 984 } else {
978 // we have been sent buggy stuff. doesn't matter 985 // we have been sent buggy stuff. doesn't matter
979 // what we do so long as we keep going. 986 // what we do so long as we keep going.
980 // should probably spit an error here 987 // should probably spit an error here
988 lexSkipLookahead();
981 c = lexLookahead(); 989 c = lexLookahead();
982 continue; 990 continue;
983 } 991 }
984 992
985 // got a valid escaped =. append it. 993 // got a valid escaped =. append it.
986 lexSkipLookahead(); // skip second 0-9A-F 994 lexSkipLookahead(); // skip second 0-9A-F
987 lexAppendc(cur); 995 lexAppendc(cur);
988 } else { 996 } else {
989 lexSkipLookahead(); // skip whatever we just read. 997 lexSkipLookahead(); // skip whatever we just read.
990 lexAppendc(c); // and append it. 998 lexAppendc(c); // and append it.
991 } 999 }
992 c = lexLookahead(); 1000 c = lexLookahead();
993 } 1001 }
994 lexAppendc(0); 1002 lexAppendc(0);
995 return c==EOF?0:lexStr(); 1003 return c==EOF?0:lexStr();
996} 1004}
997 1005
998static int yylex() { 1006static int yylex() {
999 1007
1000 int lexmode = LEXMODE(); 1008 int lexmode = LEXMODE();
1001 if (lexmode == L_VALUES) { 1009 if (lexmode == L_VALUES) {
1002 int c = lexGetc(); 1010 int c = lexGetc();
1003 if (c == ';') { 1011 if (c == ';' && fieldedProp) {
1004 DBG_(("db: SEMICOLON\n")); 1012 DBG_(("db: SEMICOLON\n"));
1005 lexPushLookaheadc(c); 1013 lexPushLookaheadc(c);
1006 handleMoreRFC822LineBreak(c); 1014 handleMoreRFC822LineBreak(c);
1007 lexSkipLookahead(); 1015 lexSkipLookahead();
1008 return SEMICOLON; 1016 return SEMICOLON;
1009 } 1017 }
1010 else if (strchr("\n",c)) { 1018 else if (strchr("\n",c)) {
1011 ++mime_lineNum; 1019 ++mime_lineNum;
1012 /* consume all line separator(s) adjacent to each other */ 1020 /* consume all line separator(s) adjacent to each other */
1013 c = lexLookahead(); 1021 c = lexLookahead();
1014 while (strchr("\n",c)) { 1022 while (strchr("\n",c)) {
1015 lexSkipLookahead(); 1023 lexSkipLookahead();
1016 c = lexLookahead(); 1024 c = lexLookahead();
1017 ++mime_lineNum; 1025 ++mime_lineNum;
1018 } 1026 }
1019 DBG_(("db: LINESEP\n")); 1027 DBG_(("db: LINESEP\n"));
1020 return LINESEP; 1028 return LINESEP;
1021 } 1029 }
1022 else { 1030 else {
1023 char *p = 0; 1031 char *p = 0;
1024 lexPushLookaheadc(c); 1032 lexPushLookaheadc(c);
1025 if (lexWithinMode(L_BASE64)) { 1033 if (lexWithinMode(L_BASE64)) {
1026 /* get each char and convert to bin on the fly... */ 1034 /* get each char and convert to bin on the fly... */
1027 p = lexGetDataFromBase64(); 1035 p = lexGetDataFromBase64();
1028 yylval.str = p; 1036 yylval.str = p;
1029 return STRING; 1037 return STRING;
1030 } 1038 }
1031 else if (lexWithinMode(L_QUOTED_PRINTABLE)) { 1039 else if (lexWithinMode(L_QUOTED_PRINTABLE)) {
1032 p = lexGetQuotedPrintable(); 1040 p = lexGetQuotedPrintable();
1033 } 1041 }
1034 else { 1042 else {
1035#ifdef _SUPPORT_LINE_FOLDING 1043#ifdef _SUPPORT_LINE_FOLDING
1036 p = lexGet1Value(); 1044 p = lexGet1Value();
1037#else 1045#else
1038 p = lexGetStrUntil(";\n"); 1046 p = lexGetStrUntil(";\n");
1039#endif 1047#endif
1040 } 1048 }
1041 if (p) { 1049 if (p) {
1042 DBG_(("db: STRING: '%s'\n", p)); 1050 DBG_(("db: STRING: '%s'\n", p));
1043 yylval.str = p; 1051 yylval.str = p;
1044 return STRING; 1052 return STRING;
1045 } 1053 }
1046 else return 0; 1054 else return 0;
1047 } 1055 }
1048 } 1056 }
1049 else { 1057 else {
1050 /* normal mode */ 1058 /* normal mode */
1051 while (1) { 1059 while (1) {
1052 int c = lexGetc(); 1060 int c = lexGetc();
1053 switch(c) { 1061 switch(c) {
1054 case ':': { 1062 case ':': {
1055 /* consume all line separator(s) adjacent to each other */ 1063 /* consume all line separator(s) adjacent to each other */
1056 /* ignoring linesep immediately after colon. */ 1064 /* ignoring linesep immediately after colon. */
1065 /* I don't see this in the spec, and it breaks null values -- WA
1057 c = lexLookahead(); 1066 c = lexLookahead();
1058 while (strchr("\n",c)) { 1067 while (strchr("\n",c)) {
1059 lexSkipLookahead(); 1068 lexSkipLookahead();
1060 c = lexLookahead(); 1069 c = lexLookahead();
1061 ++mime_lineNum; 1070 ++mime_lineNum;
1062 } 1071 }
1072 */
1063 DBG_(("db: COLON\n")); 1073 DBG_(("db: COLON\n"));
1064 return COLON; 1074 return COLON;
1065 } 1075 }
1066 case ';': 1076 case ';':
1067 DBG_(("db: SEMICOLON\n")); 1077 DBG_(("db: SEMICOLON\n"));
1068 return SEMICOLON; 1078 return SEMICOLON;
1069 case '=': 1079 case '=':
1070 DBG_(("db: EQ\n")); 1080 DBG_(("db: EQ\n"));
1071 return EQ; 1081 return EQ;
1072 /* ignore whitespace in this mode */ 1082 /* ignore whitespace in this mode */
1073 case '\t': 1083 case '\t':
1074 case ' ': continue; 1084 case ' ': continue;
1075 case '\n': { 1085 case '\n': {
1076 ++mime_lineNum; 1086 ++mime_lineNum;
1077 continue; 1087 continue;
1078 } 1088 }
1079 case EOF: return 0; 1089 case EOF: return 0;
1080 break; 1090 break;
1081 default: { 1091 default: {
1082 lexPushLookaheadc(c); 1092 lexPushLookaheadc(c);
1083 if (isalnum(c)) { 1093 if (isalnum(c)) {
1084 char *t = lexGetWord(); 1094 char *t = lexGetWord();
1085 yylval.str = t; 1095 yylval.str = t;
1086 if (!qstricmp(t, "begin")) { 1096 if (!qstricmp(t, "begin")) {
1087 return match_begin_end_name(0); 1097 return match_begin_end_name(0);
1088 } 1098 }
1089 else if (!qstricmp(t,"end")) { 1099 else if (!qstricmp(t,"end")) {
1090 return match_begin_end_name(1); 1100 return match_begin_end_name(1);
1091 } 1101 }
1092 else { 1102 else {
1093 DBG_(("db: ID '%s'\n", t)); 1103 DBG_(("db: ID '%s'\n", t));
1094 return ID; 1104 return ID;
1095 } 1105 }
1096 } 1106 }
1097 else { 1107 else {
1098 /* unknow token */ 1108 /* unknow token */
1099 return 0; 1109 return 0;
1100 } 1110 }
1101 break; 1111 break;
1102 } 1112 }
1103 } 1113 }
1104 } 1114 }
1105 } 1115 }
1106 return 0; 1116 return 0;
1107 } 1117 }
1108 1118
1109 1119
1110/***************************************************************************/ 1120/***************************************************************************/
1111 /*** Public Functions ****/ 1121 /*** Public Functions ****/
1112/***************************************************************************/ 1122/***************************************************************************/
1113 1123
1114static VObject* Parse_MIMEHelper() 1124static VObject* Parse_MIMEHelper()
1115 { 1125 {
1116 ObjStackTop = -1; 1126 ObjStackTop = -1;
1117 mime_numErrors = 0; 1127 mime_numErrors = 0;
1118 mime_lineNum = 1; 1128 mime_lineNum = 1;
1119 vObjList = 0; 1129 vObjList = 0;
1120 curObj = 0; 1130 curObj = 0;
1121 1131
1122 if (yyparse() != 0) 1132 if (yyparse() != 0)
1123 return 0; 1133 return 0;
1124 1134
1125 finiLex(); 1135 finiLex();
1126 return vObjList; 1136 return vObjList;
1127 } 1137 }
1128 1138
1129/*--------------------------------------------*/ 1139/*--------------------------------------------*/
1130DLLEXPORT(VObject*) Parse_MIME(const char *input, unsigned long len) 1140DLLEXPORT(VObject*) Parse_MIME(const char *input, unsigned long len)
1131 { 1141 {
1132 initLex(input, len, 0); 1142 initLex(input, len, 0);
1133 return Parse_MIMEHelper(); 1143 return Parse_MIMEHelper();
1134 } 1144 }
1135 1145
1136 1146
1137#if INCLUDEMFC 1147#if INCLUDEMFC
1138 1148
1139DLLEXPORT(VObject*) Parse_MIME_FromFile(CFile *file) 1149DLLEXPORT(VObject*) Parse_MIME_FromFile(CFile *file)
1140 { 1150 {
1141 unsigned long startPos; 1151 unsigned long startPos;
1142 VObject *result; 1152 VObject *result;
1143 1153
1144 initLex(0,-1,file); 1154 initLex(0,-1,file);
1145 startPos = file->GetPosition(); 1155 startPos = file->GetPosition();
1146 if (!(result = Parse_MIMEHelper())) 1156 if (!(result = Parse_MIMEHelper()))
1147 file->Seek(startPos, CFile::begin); 1157 file->Seek(startPos, CFile::begin);
1148 return result; 1158 return result;
1149 } 1159 }
1150 1160
1151#else 1161#else
1152 1162
1153VObject* Parse_MIME_FromFile(FILE *file) 1163VObject* Parse_MIME_FromFile(FILE *file)
1154 { 1164 {
1155 VObject *result; 1165 VObject *result;
1156 long startPos; 1166 long startPos;
1157 1167
1158 initLex(0,(unsigned long)-1,file); 1168 initLex(0,(unsigned long)-1,file);
diff --git a/library/backend/vcc_yacc.cpp b/library/backend/vcc_yacc.cpp
index b2b0c14..5649522 100644
--- a/library/backend/vcc_yacc.cpp
+++ b/library/backend/vcc_yacc.cpp
@@ -65,193 +65,193 @@ DAMAGE.
65 65
66EACH LICENSOR SPECIFICALLY DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, 66EACH LICENSOR SPECIFICALLY DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED,
67INCLUDING BUT NOT LIMITED TO ANY WARRANTY OF NONINFRINGEMENT OR THE 67INCLUDING BUT NOT LIMITED TO ANY WARRANTY OF NONINFRINGEMENT OR THE
68IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 68IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
69PURPOSE. 69PURPOSE.
70 70
71The software is provided with RESTRICTED RIGHTS. Use, duplication, or 71The software is provided with RESTRICTED RIGHTS. Use, duplication, or
72disclosure by the government are subject to restrictions set forth in 72disclosure by the government are subject to restrictions set forth in
73DFARS 252.227-7013 or 48 CFR 52.227-19, as applicable. 73DFARS 252.227-7013 or 48 CFR 52.227-19, as applicable.
74 74
75***************************************************************************/ 75***************************************************************************/
76 76
77/* 77/*
78 * src: vcc.c 78 * src: vcc.c
79 * doc: Parser for vCard and vCalendar. Note that this code is 79 * doc: Parser for vCard and vCalendar. Note that this code is
80 * generated by a yacc parser generator. Generally it should not 80 * generated by a yacc parser generator. Generally it should not
81 * be edited by hand. The real source is vcc.y. The #line directives 81 * be edited by hand. The real source is vcc.y. The #line directives
82 * can be commented out here to make it easier to trace through 82 * can be commented out here to make it easier to trace through
83 * in a debugger. However, if a bug is found it should 83 * in a debugger. However, if a bug is found it should
84 * be fixed in vcc.y and this file regenerated. 84 * be fixed in vcc.y and this file regenerated.
85 */ 85 */
86 86
87 87
88/* debugging utilities */ 88/* debugging utilities */
89#if __DEBUG 89#if __DEBUG
90#define DBG_(x) printf x 90#define DBG_(x) printf x
91#else 91#else
92#define DBG_(x) 92#define DBG_(x)
93#endif 93#endif
94 94
95/**** External Functions ****/ 95/**** External Functions ****/
96 96
97/* assign local name to parser variables and functions so that 97/* assign local name to parser variables and functions so that
98 we can use more than one yacc based parser. 98 we can use more than one yacc based parser.
99*/ 99*/
100 100
101#if 0 101#if 0
102#define yyparse mime_parse 102#define yyparse mime_parse
103#define yylex mime_lex 103#define yylex mime_lex
104#define yyerror mime_error 104#define yyerror mime_error
105#define yychar mime_char 105#define yychar mime_char
106/* #define p_yyval p_mime_val */ 106/* #define p_yyval p_mime_val */
107#undef yyval 107#undef yyval
108#define yyval mime_yyval 108#define yyval mime_yyval
109/* #define p_yylval p_mime_lval */ 109/* #define p_yylval p_mime_lval */
110#undef yylval 110#undef yylval
111#define yylval mime_yylval 111#define yylval mime_yylval
112#define yydebug mime_debug 112#define yydebug mime_debug
113#define yynerrs mime_nerrs 113#define yynerrs mime_nerrs
114#define yyerrflag mime_errflag 114#define yyerrflag mime_errflag
115#define yyss mime_ss 115#define yyss mime_ss
116#define yyssp mime_ssp 116#define yyssp mime_ssp
117#define yyvs mime_vs 117#define yyvs mime_vs
118#define yyvsp mime_vsp 118#define yyvsp mime_vsp
119#define yylhs mime_lhs 119#define yylhs mime_lhs
120#define yylen mime_len 120#define yylen mime_len
121#define yydefred mime_defred 121#define yydefred mime_defred
122#define yydgoto mime_dgoto 122#define yydgoto mime_dgoto
123#define yysindex mime_sindex 123#define yysindex mime_sindex
124#define yyrindex mime_rindex 124#define yyrindex mime_rindex
125#define yygindex mime_gindex 125#define yygindex mime_gindex
126#define yytable mime_table 126#define yytable mime_table
127#define yycheck mime_check 127#define yycheck mime_check
128#define yyname mime_name 128#define yyname mime_name
129#define yyrule mime_rule 129#define yyrule mime_rule
130#ifdef YYPREFIX 130#ifdef YYPREFIX
131#undef YYPREFIX 131#undef YYPREFIX
132#endif 132#endif
133#define YYPREFIX "mime_" 133#define YYPREFIX "mime_"
134#endif 134#endif
135 135
136 136
137#ifndef _NO_LINE_FOLDING 137#ifndef _NO_LINE_FOLDING
138#define _SUPPORT_LINE_FOLDING 1 138#define _SUPPORT_LINE_FOLDING 1
139#endif 139#endif
140 140
141/* undef below if compile with MFC */ 141/* undef below if compile with MFC */
142/* #define INCLUDEMFC 1 */ 142/* #define INCLUDEMFC 1 */
143 143
144#if defined(WIN32) || defined(_WIN32) 144#if defined(WIN32) || defined(_WIN32)
145#ifdef INCLUDEMFC 145#ifdef INCLUDEMFC
146#include <afx.h> 146#include <afx.h>
147#endif 147#endif
148#endif 148#endif
149 149
150#include <string.h> 150#include <string.h>
151#ifndef __MWERKS__ 151#ifndef __MWERKS__
152#include <stdlib.h> 152#include <stdlib.h>
153#endif 153#endif
154#include <stdio.h> 154#include <stdio.h>
155#include <stdlib.h> 155#include <stdlib.h>
156#include <ctype.h> 156#include <ctype.h>
157 157
158/*#ifdef PALMTOPCENTER */ 158/*#ifdef PALMTOPCENTER */
159/*#include <qpe/vobject_p.h> */ 159/*#include <qpe/vobject_p.h> */
160/*#else */ 160/*#else */
161#include <qtopia/private/vobject_p.h> 161#include "vobject_p.h"
162/*#endif */ 162/*#endif */
163 163
164/**** Types, Constants ****/ 164/**** Types, Constants ****/
165 165
166 #define YYDEBUG 0/* 1 to compile in some debugging code */ 166 #define YYDEBUG 0/* 1 to compile in some debugging code */
167 #define MAXTOKEN 256/* maximum token (line) length */ 167 #define MAXTOKEN 256/* maximum token (line) length */
168 #define YYSTACKSIZE 100/* ~unref ? */ 168 #define YYSTACKSIZE 100/* ~unref ? */
169 #define MAXLEVEL 10/* max # of nested objects parseable */ 169 #define MAXLEVEL 10/* max # of nested objects parseable */
170 /* (includes outermost) */ 170 /* (includes outermost) */
171 171
172 172
173/**** Global Variables ****/ 173/**** Global Variables ****/
174int mime_lineNum, mime_numErrors; /* yyerror() can use these */ 174int mime_lineNum, mime_numErrors; /* yyerror() can use these */
175static VObject* vObjList; 175static VObject* vObjList;
176static VObject *curProp; 176static VObject *curProp;
177static VObject *curObj; 177static VObject *curObj;
178static VObject* ObjStack[MAXLEVEL]; 178static VObject* ObjStack[MAXLEVEL];
179static int ObjStackTop; 179static int ObjStackTop;
180 180
181 181
182/* A helpful utility for the rest of the app. */ 182/* A helpful utility for the rest of the app. */
183#if __CPLUSPLUS__ 183#if __CPLUSPLUS__
184extern "C" { 184extern "C" {
185#endif 185#endif
186 186
187 extern void yyerror(char *s); 187 extern void yyerror(char *s);
188 188
189#if __CPLUSPLUS__ 189#if __CPLUSPLUS__
190 }; 190 };
191#endif 191#endif
192 192
193int yyparse(); 193int yyparse();
194 194
195enum LexMode { 195enum LexMode {
196 L_NORMAL, 196 L_NORMAL,
197 L_VCARD, 197 L_VCARD,
198 L_VCAL, 198 L_VCAL,
199 L_VEVENT, 199 L_VEVENT,
200 L_VTODO, 200 L_VTODO,
201 L_VALUES, 201 L_VALUES,
202 L_BASE64, 202 L_BASE64,
203 L_QUOTED_PRINTABLE 203 L_QUOTED_PRINTABLE
204 }; 204 };
205 205
206/**** Private Forward Declarations ****/ 206/**** Private Forward Declarations ****/
207static int pushVObject(const char *prop); 207static int pushVObject(const char *prop);
208static VObject* popVObject(); 208static VObject* popVObject();
209static void lexPopMode(int top); 209static void lexPopMode(int top);
210static int lexWithinMode(enum LexMode mode); 210static int lexWithinMode(enum LexMode mode);
211static void lexPushMode(enum LexMode mode); 211static void lexPushMode(enum LexMode mode);
212static void enterProps(const char *s); 212static void enterProps(const char *s);
213static void enterAttr(const char *s1, const char *s2); 213static void enterAttr(const char *s1, const char *s2);
214static void enterValues(const char *value); 214static void enterValues(const char *value);
215#define mime_error yyerror 215#define mime_error yyerror
216void mime_error(char *s); 216void mime_error(char *s);
217void mime_error_(char *s); 217void mime_error_(char *s);
218 218
219#line 189 "backend/vcc.y" 219#line 189 "backend/vcc.y"
220typedef union { 220typedef union {
221 char *str; 221 char *str;
222 VObject *vobj; 222 VObject *vobj;
223 } YYSTYPE; 223 } YYSTYPE;
224#line 225 "y.tab.c" 224#line 225 "y.tab.c"
225#define EQ 257 225#define EQ 257
226#define COLON 258 226#define COLON 258
227#define DOT 259 227#define DOT 259
228#define SEMICOLON 260 228#define SEMICOLON 260
229#define SPACE 261 229#define SPACE 261
230#define HTAB 262 230#define HTAB 262
231#define LINESEP 263 231#define LINESEP 263
232#define NEWLINE 264 232#define NEWLINE 264
233#define BEGIN_VCARD 265 233#define BEGIN_VCARD 265
234#define END_VCARD 266 234#define END_VCARD 266
235#define BEGIN_VCAL 267 235#define BEGIN_VCAL 267
236#define END_VCAL 268 236#define END_VCAL 268
237#define BEGIN_VEVENT 269 237#define BEGIN_VEVENT 269
238#define END_VEVENT 270 238#define END_VEVENT 270
239#define BEGIN_VTODO 271 239#define BEGIN_VTODO 271
240#define END_VTODO 272 240#define END_VTODO 272
241#define ID 273 241#define ID 273
242#define STRING 274 242#define STRING 274
243#define YYERRCODE 256 243#define YYERRCODE 256
244short vcclhs[] = { -1, 244short vcclhs[] = { -1,
245 0, 6, 6, 5, 5, 8, 3, 9, 3, 7, 245 0, 6, 6, 5, 5, 8, 3, 9, 3, 7,
246 7, 13, 10, 10, 15, 11, 11, 14, 14, 16, 246 7, 13, 10, 10, 15, 11, 11, 14, 14, 16,
247 17, 17, 1, 18, 12, 12, 2, 2, 20, 4, 247 17, 17, 1, 18, 12, 12, 2, 2, 20, 4,
248 21, 4, 19, 19, 22, 22, 22, 25, 23, 26, 248 21, 4, 19, 19, 22, 22, 22, 25, 23, 26,
249 23, 27, 24, 28, 24, 249 23, 27, 24, 28, 24,
250}; 250};
251short vcclen[] = { 2, 251short vcclen[] = { 2,
252 1, 2, 1, 1, 1, 0, 4, 0, 3, 2, 252 1, 2, 1, 1, 1, 0, 4, 0, 3, 2,
253 1, 0, 5, 1, 0, 3, 1, 2, 1, 2, 253 1, 0, 5, 1, 0, 3, 1, 2, 1, 2,
254 1, 3, 1, 0, 4, 1, 1, 0, 0, 4, 254 1, 3, 1, 0, 4, 1, 1, 0, 0, 4,
255 0, 3, 2, 1, 1, 1, 1, 0, 4, 0, 255 0, 3, 2, 1, 1, 1, 1, 0, 4, 0,
256 3, 0, 4, 0, 3, 256 3, 0, 4, 0, 3,
257}; 257};
@@ -650,202 +650,208 @@ static void lexSkipWhite() {
650static char* lexGetWord() { 650static char* lexGetWord() {
651 int c; 651 int c;
652 lexSkipWhite(); 652 lexSkipWhite();
653 lexClearToken(); 653 lexClearToken();
654 c = lexLookahead(); 654 c = lexLookahead();
655 while (c != EOF && !strchr("\t\n ;:=",c)) { 655 while (c != EOF && !strchr("\t\n ;:=",c)) {
656 lexAppendc(c); 656 lexAppendc(c);
657 lexSkipLookahead(); 657 lexSkipLookahead();
658 c = lexLookahead(); 658 c = lexLookahead();
659 } 659 }
660 lexAppendc(0); 660 lexAppendc(0);
661 return lexStr(); 661 return lexStr();
662 } 662 }
663 663
664static void lexPushLookaheadc(int c) { 664static void lexPushLookaheadc(int c) {
665 int putptr; 665 int putptr;
666 /* can't putback EOF, because it never leaves lookahead buffer */ 666 /* can't putback EOF, because it never leaves lookahead buffer */
667 if (c == EOF) return; 667 if (c == EOF) return;
668 putptr = (int)lexBuf.getPtr - 1; 668 putptr = (int)lexBuf.getPtr - 1;
669 if (putptr < 0) putptr += MAX_LEX_LOOKAHEAD; 669 if (putptr < 0) putptr += MAX_LEX_LOOKAHEAD;
670 lexBuf.getPtr = putptr; 670 lexBuf.getPtr = putptr;
671 lexBuf.buf[putptr] = c; 671 lexBuf.buf[putptr] = c;
672 lexBuf.len += 1; 672 lexBuf.len += 1;
673 } 673 }
674 674
675static char* lexLookaheadWord() { 675static char* lexLookaheadWord() {
676 /* this function can lookahead word with max size of MAX_LEX_LOOKAHEAD_0 676 /* this function can lookahead word with max size of MAX_LEX_LOOKAHEAD_0
677 / and thing bigger than that will stop the lookahead and return 0; 677 / and thing bigger than that will stop the lookahead and return 0;
678 / leading white spaces are not recoverable. 678 / leading white spaces are not recoverable.
679 */ 679 */
680 int c; 680 int c;
681 int len = 0; 681 int len = 0;
682 int curgetptr = 0; 682 int curgetptr = 0;
683 lexSkipWhite(); 683 lexSkipWhite();
684 lexClearToken(); 684 lexClearToken();
685 curgetptr = (int)lexBuf.getPtr;// remember! 685 curgetptr = (int)lexBuf.getPtr;// remember!
686 while (len < (MAX_LEX_LOOKAHEAD_0)) { 686 while (len < (MAX_LEX_LOOKAHEAD_0)) {
687 c = lexGetc(); 687 c = lexGetc();
688 len++; 688 len++;
689 if (c == EOF || strchr("\t\n ;:=", c)) { 689 if (c == EOF || strchr("\t\n ;:=", c)) {
690 lexAppendc(0); 690 lexAppendc(0);
691 /* restore lookahead buf. */ 691 /* restore lookahead buf. */
692 lexBuf.len += len; 692 lexBuf.len += len;
693 lexBuf.getPtr = curgetptr; 693 lexBuf.getPtr = curgetptr;
694 return lexStr(); 694 return lexStr();
695 } 695 }
696 else 696 else
697 lexAppendc(c); 697 lexAppendc(c);
698 } 698 }
699 lexBuf.len += len;/* char that has been moved to lookahead buffer */ 699 lexBuf.len += len;/* char that has been moved to lookahead buffer */
700 lexBuf.getPtr = curgetptr; 700 lexBuf.getPtr = curgetptr;
701 return 0; 701 return 0;
702 } 702 }
703 703
704#ifdef _SUPPORT_LINE_FOLDING 704#ifdef _SUPPORT_LINE_FOLDING
705static void handleMoreRFC822LineBreak(int c) { 705static void handleMoreRFC822LineBreak(int c) {
706 /* suport RFC 822 line break in cases like 706 /* suport RFC 822 line break in cases like
707 *ADR: foo; 707 *ADR: foo;
708 * morefoo; 708 * morefoo;
709 * more foo; 709 * more foo;
710 */ 710 */
711 if (c == ';') { 711 if (c == ';') {
712 int a; 712 int a;
713 lexSkipLookahead(); 713 lexSkipLookahead();
714 /* skip white spaces */ 714 /* skip white spaces */
715 a = lexLookahead(); 715 a = lexLookahead();
716 while (a == ' ' || a == '\t') { 716 while (a == ' ' || a == '\t') {
717 lexSkipLookahead(); 717 lexSkipLookahead();
718 a = lexLookahead(); 718 a = lexLookahead();
719 } 719 }
720 if (a == '\n') { 720 if (a == '\n') {
721 lexSkipLookahead(); 721 lexSkipLookahead();
722 a = lexLookahead(); 722 a = lexLookahead();
723 if (a == ' ' || a == '\t') { 723 if (a == ' ' || a == '\t') {
724 /* continuation, throw away all the \n and spaces read so 724 /* continuation, throw away all the \n and spaces read so
725 * far 725 * far
726 */ 726 */
727 lexSkipWhite(); 727 lexSkipWhite();
728 lexPushLookaheadc(';'); 728 lexPushLookaheadc(';');
729 } 729 }
730 else { 730 else {
731 lexPushLookaheadc('\n'); 731 lexPushLookaheadc('\n');
732 lexPushLookaheadc(';'); 732 lexPushLookaheadc(';');
733 } 733 }
734 } 734 }
735 else { 735 else {
736 lexPushLookaheadc(';'); 736 lexPushLookaheadc(';');
737 } 737 }
738 } 738 }
739 } 739 }
740 740
741static char* lexGet1Value() { 741static char* lexGet1Value() {
742 int c; 742 int c;
743 lexSkipWhite(); 743 lexSkipWhite();
744 c = lexLookahead(); 744 c = lexLookahead();
745 lexClearToken(); 745 lexClearToken();
746 while (c != EOF && c != ';') { 746 while (c != EOF && (c != ';' || !fieldedProp)) {
747 if (c == '\\' ) { 747 if (c == '\\' ) {
748 int a; 748 int a;
749 lexSkipLookahead(); 749 lexSkipLookahead();
750 a = lexLookahead(); 750 a = lexLookahead();
751 if ( a != ';' ) { 751 if ( a == ';' ) {
752 lexAppendc('\\');
753 } else {
754 lexAppendc( ';' ); 752 lexAppendc( ';' );
755 lexSkipLookahead(); 753 lexSkipLookahead();
754 } else if ( a == '\n' ) {
755 lexAppendc( '\n' );
756 lexSkipLookahead();
757 } else if ( a == '\\' ) {
758 lexAppendc( '\\' );
759 lexSkipLookahead();
760 } else {
761 lexAppendc('\\');
756 } 762 }
757 } else if (c == '\n') { 763 } else if (c == '\n') {
758 int a; 764 int a;
759 lexSkipLookahead(); 765 lexSkipLookahead();
760 a = lexLookahead(); 766 a = lexLookahead();
761 if (a == ' ' || a == '\t') { 767 if (a == ' ' || a == '\t') {
762 lexAppendc(' '); 768 lexAppendc(' ');
763 lexSkipLookahead(); 769 lexSkipLookahead();
764 } 770 }
765 else { 771 else {
766 lexPushLookaheadc('\n'); 772 lexPushLookaheadc('\n');
767 break; 773 break;
768 } 774 }
769 } 775 }
770 else { 776 else {
771 lexAppendc(c); 777 lexAppendc(c);
772 lexSkipLookahead(); 778 lexSkipLookahead();
773 } 779 }
774 c = lexLookahead(); 780 c = lexLookahead();
775 } 781 }
776 lexAppendc(0); 782 lexAppendc(0);
777 handleMoreRFC822LineBreak(c); 783 handleMoreRFC822LineBreak(c);
778 return c==EOF?0:lexStr(); 784 return c==EOF?0:lexStr();
779 } 785 }
780#endif 786#endif
781 787
782static int match_begin_name(int end) { 788static int match_begin_name(int end) {
783 char *n = lexLookaheadWord(); 789 char *n = lexLookaheadWord();
784 int token = ID; 790 int token = ID;
785 if (n) { 791 if (n) {
786 if (!qstricmp(n,"vcard")) token = end?END_VCARD:BEGIN_VCARD; 792 if (!qstricmp(n,"vcard")) token = end?END_VCARD:BEGIN_VCARD;
787 else if (!qstricmp(n,"vcalendar")) token = end?END_VCAL:BEGIN_VCAL; 793 else if (!qstricmp(n,"vcalendar")) token = end?END_VCAL:BEGIN_VCAL;
788 else if (!qstricmp(n,"vevent")) token = end?END_VEVENT:BEGIN_VEVENT; 794 else if (!qstricmp(n,"vevent")) token = end?END_VEVENT:BEGIN_VEVENT;
789 else if (!qstricmp(n,"vtodo")) token = end?END_VTODO:BEGIN_VTODO; 795 else if (!qstricmp(n,"vtodo")) token = end?END_VTODO:BEGIN_VTODO;
790 deleteStr(n); 796 deleteStr(n);
791 return token; 797 return token;
792 } 798 }
793 return 0; 799 return 0;
794 } 800 }
795 801
796 802
797#ifdef INCLUDEMFC 803#ifdef INCLUDEMFC
798void initLex(const char *inputstring, unsigned long inputlen, CFile *inputfile) 804void initLex(const char *inputstring, unsigned long inputlen, CFile *inputfile)
799#else 805#else
800void initLex(const char *inputstring, unsigned long inputlen, FILE *inputfile) 806void initLex(const char *inputstring, unsigned long inputlen, FILE *inputfile)
801#endif 807#endif
802 { 808 {
803 // initialize lex mode stack 809 // initialize lex mode stack
804 lexBuf.lexModeStack[lexBuf.lexModeStackTop=0] = L_NORMAL; 810 lexBuf.lexModeStack[lexBuf.lexModeStackTop=0] = L_NORMAL;
805 811
806 // iniatialize lex buffer. 812 // iniatialize lex buffer.
807 lexBuf.inputString = (char*) inputstring; 813 lexBuf.inputString = (char*) inputstring;
808 lexBuf.inputLen = inputlen; 814 lexBuf.inputLen = inputlen;
809 lexBuf.curPos = 0; 815 lexBuf.curPos = 0;
810 lexBuf.inputFile = inputfile; 816 lexBuf.inputFile = inputfile;
811 817
812 lexBuf.len = 0; 818 lexBuf.len = 0;
813 lexBuf.getPtr = 0; 819 lexBuf.getPtr = 0;
814 820
815 lexBuf.maxToken = MAXTOKEN; 821 lexBuf.maxToken = MAXTOKEN;
816 lexBuf.strs = (char*)malloc(MAXTOKEN); 822 lexBuf.strs = (char*)malloc(MAXTOKEN);
817 lexBuf.strsLen = 0; 823 lexBuf.strsLen = 0;
818 824
819 } 825 }
820 826
821static void finiLex() { 827static void finiLex() {
822 free(lexBuf.strs); 828 free(lexBuf.strs);
823 } 829 }
824 830
825 831
826/*-----------------------------------*/ 832/*-----------------------------------*/
827/* This parses and converts the base64 format for binary encoding into 833/* This parses and converts the base64 format for binary encoding into
828 * a decoded buffer (allocated with new). See RFC 1521. 834 * a decoded buffer (allocated with new). See RFC 1521.
829 */ 835 */
830static char * lexGetDataFromBase64() 836static char * lexGetDataFromBase64()
831 { 837 {
832 unsigned long bytesLen = 0, bytesMax = 0; 838 unsigned long bytesLen = 0, bytesMax = 0;
833 int quadIx = 0, pad = 0; 839 int quadIx = 0, pad = 0;
834 unsigned long trip = 0; 840 unsigned long trip = 0;
835 unsigned char b; 841 unsigned char b;
836 int c; 842 int c;
837 unsigned char *bytes = NULL; 843 unsigned char *bytes = NULL;
838 unsigned char *oldBytes = NULL; 844 unsigned char *oldBytes = NULL;
839 845
840 DBG_(("db: lexGetDataFromBase64\n")); 846 DBG_(("db: lexGetDataFromBase64\n"));
841 while (1) { 847 while (1) {
842 c = lexGetc(); 848 c = lexGetc();
843 if (c == '\n') { 849 if (c == '\n') {
844 ++mime_lineNum; 850 ++mime_lineNum;
845 if (lexLookahead() == '\n') { 851 if (lexLookahead() == '\n') {
846 /* a '\n' character by itself means end of data */ 852 /* a '\n' character by itself means end of data */
847 break; 853 break;
848 } 854 }
849 else continue; /* ignore '\n' */ 855 else continue; /* ignore '\n' */
850 } 856 }
851 else { 857 else {
@@ -857,460 +863,473 @@ static char * lexGetDataFromBase64()
857 b = (unsigned char)(c - '0') + 52; 863 b = (unsigned char)(c - '0') + 52;
858 else if (c == '+') 864 else if (c == '+')
859 b = 62; 865 b = 62;
860 else if (c == '/') 866 else if (c == '/')
861 b = 63; 867 b = 63;
862 else if (c == '=') { 868 else if (c == '=') {
863 b = 0; 869 b = 0;
864 pad++; 870 pad++;
865 } else if ((c == ' ') || (c == '\t')) { 871 } else if ((c == ' ') || (c == '\t')) {
866 continue; 872 continue;
867 } else { /* error condition */ 873 } else { /* error condition */
868 if (bytes) free(bytes); 874 if (bytes) free(bytes);
869 else if (oldBytes) free(oldBytes); 875 else if (oldBytes) free(oldBytes);
870 // error recovery: skip until 2 adjacent newlines. 876 // error recovery: skip until 2 adjacent newlines.
871 DBG_(("db: invalid character 0x%x '%c'\n", c,c)); 877 DBG_(("db: invalid character 0x%x '%c'\n", c,c));
872 if (c != EOF) { 878 if (c != EOF) {
873 c = lexGetc(); 879 c = lexGetc();
874 while (c != EOF) { 880 while (c != EOF) {
875 if (c == '\n' && lexLookahead() == '\n') { 881 if (c == '\n' && lexLookahead() == '\n') {
876 ++mime_lineNum; 882 ++mime_lineNum;
877 break; 883 break;
878 } 884 }
879 c = lexGetc(); 885 c = lexGetc();
880 } 886 }
881 } 887 }
882 return NULL; 888 return NULL;
883 } 889 }
884 trip = (trip << 6) | b; 890 trip = (trip << 6) | b;
885 if (++quadIx == 4) { 891 if (++quadIx == 4) {
886 unsigned char outBytes[3]; 892 unsigned char outBytes[3];
887 int numOut; 893 int numOut;
888 int i; 894 int i;
889 for (i = 0; i < 3; i++) { 895 for (i = 0; i < 3; i++) {
890 outBytes[2-i] = (unsigned char)(trip & 0xFF); 896 outBytes[2-i] = (unsigned char)(trip & 0xFF);
891 trip >>= 8; 897 trip >>= 8;
892 } 898 }
893 numOut = 3 - pad; 899 numOut = 3 - pad;
894 if (bytesLen + numOut > bytesMax) { 900 if (bytesLen + numOut > bytesMax) {
895 if (!bytes) { 901 if (!bytes) {
896 bytesMax = 1024; 902 bytesMax = 1024;
897 bytes = (unsigned char*)malloc((size_t)bytesMax); 903 bytes = (unsigned char*)malloc((size_t)bytesMax);
898 } 904 }
899 else { 905 else {
900 bytesMax <<= 2; 906 bytesMax <<= 2;
901 oldBytes = bytes; 907 oldBytes = bytes;
902 bytes = (unsigned char*)realloc(bytes,(size_t)bytesMax); 908 bytes = (unsigned char*)realloc(bytes,(size_t)bytesMax);
903 } 909 }
904 if (bytes == 0) { 910 if (bytes == 0) {
905 mime_error("out of memory while processing BASE64 data\n"); 911 mime_error("out of memory while processing BASE64 data\n");
906 } 912 }
907 } 913 }
908 if (bytes) { 914 if (bytes) {
909 memcpy(bytes + bytesLen, outBytes, numOut); 915 memcpy(bytes + bytesLen, outBytes, numOut);
910 bytesLen += numOut; 916 bytesLen += numOut;
911 } 917 }
912 trip = 0; 918 trip = 0;
913 quadIx = 0; 919 quadIx = 0;
914 } 920 }
915 } 921 }
916 } /* while */ 922 } /* while */
917 DBG_(("db: bytesLen = %d\n", bytesLen)); 923 DBG_(("db: bytesLen = %d\n", bytesLen));
918 /* kludge: all this won't be necessary if we have tree form 924 /* kludge: all this won't be necessary if we have tree form
919 representation */ 925 representation */
920 if (bytes) { 926 if (bytes) {
921 setValueWithSize(curProp,bytes,(unsigned int)bytesLen); 927 setValueWithSize(curProp,bytes,(unsigned int)bytesLen);
922 free(bytes); 928 free(bytes);
923 } 929 }
924 else if (oldBytes) { 930 else if (oldBytes) {
925 setValueWithSize(curProp,oldBytes,(unsigned int)bytesLen); 931 setValueWithSize(curProp,oldBytes,(unsigned int)bytesLen);
926 free(oldBytes); 932 free(oldBytes);
927 } 933 }
928 return 0; 934 return 0;
929 } 935 }
930 936
931static int match_begin_end_name(int end) { 937static int match_begin_end_name(int end) {
932 int token; 938 int token;
933 lexSkipWhite(); 939 lexSkipWhite();
934 if (lexLookahead() != ':') return ID; 940 if (lexLookahead() != ':') return ID;
935 lexSkipLookahead(); 941 lexSkipLookahead();
936 lexSkipWhite(); 942 lexSkipWhite();
937 token = match_begin_name(end); 943 token = match_begin_name(end);
938 if (token == ID) { 944 if (token == ID) {
939 lexPushLookaheadc(':'); 945 lexPushLookaheadc(':');
940 DBG_(("db: ID '%s'\n", yylval.str)); 946 DBG_(("db: ID '%s'\n", yylval.str));
941 return ID; 947 return ID;
942 } 948 }
943 else if (token != 0) { 949 else if (token != 0) {
944 lexSkipLookaheadWord(); 950 lexSkipLookaheadWord();
945 deleteStr(yylval.str); 951 deleteStr(yylval.str);
946 DBG_(("db: begin/end %d\n", token)); 952 DBG_(("db: begin/end %d\n", token));
947 return token; 953 return token;
948 } 954 }
949 return 0; 955 return 0;
950 } 956 }
951 957
952static char* lexGetQuotedPrintable() 958static char* lexGetQuotedPrintable()
953 { 959{
954 int cur; 960 int c;
955 961 lexSkipWhite();
962 c = lexLookahead();
956 lexClearToken(); 963 lexClearToken();
957 do {
958 cur = lexGetc();
959 switch (cur) {
960 case '=': {
961 int c = 0;
962 int next[2];
963 int i;
964 for (i = 0; i < 2; i++) {
965 next[i] = lexGetc();
966 if (next[i] >= '0' && next[i] <= '9')
967 c = c * 16 + next[i] - '0';
968 else if (next[i] >= 'A' && next[i] <= 'F')
969 c = c * 16 + next[i] - 'A' + 10;
970 else
971 break;
972 }
973 if (i == 0) {
974 /* single '=' follow by LINESEP is continuation sign? */
975 if (next[0] == '\n') {
976 ++mime_lineNum;
977 }
978 else {
979 lexPushLookaheadc('=');
980 goto EndString;
981 }
982 }
983 else if (i == 1) {
984 lexPushLookaheadc(next[1]);
985 lexPushLookaheadc(next[0]);
986 lexAppendc('=');
987 } else {
988 lexAppendc(c);
989 }
990 break;
991 } /* '=' */
992 case '\n': {
993 lexPushLookaheadc('\n');
994 goto EndString;
995 }
996 case (int)EOF:
997 break;
998 default:
999 lexAppendc(cur);
1000 break;
1001 } /* switch */
1002 } while (cur != (int)EOF);
1003 964
1004EndString: 965 while (c != EOF && c != ';') {
966 if (c == '\n') {
967 // break, leave '\n' on remaining chars.
968 break;
969 } else if (c == '=') {
970 int cur = 0;
971 int next;
972
973 lexSkipLookahead(); // skip '='
974 next = lexLookahead();
975
976 if (next == '\n') {
977 // skip and only skip the \n
978 lexSkipLookahead();
979 c = lexLookahead();
980 ++mime_lineNum; // aid in error reporting
981 continue;
982 } else if (next >= '0' && next <= '9') {
983 cur = next - '0';
984 } else if (next >= 'A' && next <= 'F') {
985 cur = next - 'A' + 10;
986 } else {
987 // we have been sent buggy stuff. doesn't matter
988 // what we do so long as we keep going.
989 // should probably spit an error here
990 lexSkipLookahead();
991 c = lexLookahead();
992 continue;
993 }
994
995 lexSkipLookahead(); // skip A-Z0-9
996 next = lexLookahead();
997
998 cur = cur * 16;
999 // this time really just expecting 0-9A-F
1000 if (next >= '0' && next <= '9') {
1001 cur += next - '0';
1002 } else if (next >= 'A' && next <= 'F') {
1003 cur += next - 'A' + 10;
1004 } else {
1005 // we have been sent buggy stuff. doesn't matter
1006 // what we do so long as we keep going.
1007 // should probably spit an error here
1008 lexSkipLookahead();
1009 c = lexLookahead();
1010 continue;
1011 }
1012
1013 // got a valid escaped =. append it.
1014 lexSkipLookahead(); // skip second 0-9A-F
1015 lexAppendc(cur);
1016 } else {
1017 lexSkipLookahead(); // skip whatever we just read.
1018 lexAppendc(c); // and append it.
1019 }
1020 c = lexLookahead();
1021 }
1005 lexAppendc(0); 1022 lexAppendc(0);
1006 return lexStr(); 1023 return c==EOF?0:lexStr();
1007 } /* LexQuotedPrintable */ 1024}
1008 1025
1009static int yylex() { 1026static int yylex() {
1010 1027
1011 int lexmode = LEXMODE(); 1028 int lexmode = LEXMODE();
1012 if (lexmode == L_VALUES) { 1029 if (lexmode == L_VALUES) {
1013 int c = lexGetc(); 1030 int c = lexGetc();
1014 if (c == ';') { 1031 if (c == ';' && fieldedProp) {
1015 DBG_(("db: SEMICOLON\n")); 1032 DBG_(("db: SEMICOLON\n"));
1016 lexPushLookaheadc(c); 1033 lexPushLookaheadc(c);
1017 handleMoreRFC822LineBreak(c); 1034 handleMoreRFC822LineBreak(c);
1018 lexSkipLookahead(); 1035 lexSkipLookahead();
1019 return SEMICOLON; 1036 return SEMICOLON;
1020 } 1037 }
1021 else if (strchr("\n",c)) { 1038 else if (strchr("\n",c)) {
1022 ++mime_lineNum; 1039 ++mime_lineNum;
1023 /* consume all line separator(s) adjacent to each other */ 1040 /* consume all line separator(s) adjacent to each other */
1024 c = lexLookahead(); 1041 c = lexLookahead();
1025 while (strchr("\n",c)) { 1042 while (strchr("\n",c)) {
1026 lexSkipLookahead(); 1043 lexSkipLookahead();
1027 c = lexLookahead(); 1044 c = lexLookahead();
1028 ++mime_lineNum; 1045 ++mime_lineNum;
1029 } 1046 }
1030 DBG_(("db: LINESEP\n")); 1047 DBG_(("db: LINESEP\n"));
1031 return LINESEP; 1048 return LINESEP;
1032 } 1049 }
1033 else { 1050 else {
1034 char *p = 0; 1051 char *p = 0;
1035 lexPushLookaheadc(c); 1052 lexPushLookaheadc(c);
1036 if (lexWithinMode(L_BASE64)) { 1053 if (lexWithinMode(L_BASE64)) {
1037 /* get each char and convert to bin on the fly... */ 1054 /* get each char and convert to bin on the fly... */
1038 p = lexGetDataFromBase64(); 1055 p = lexGetDataFromBase64();
1039 yylval.str = p; 1056 yylval.str = p;
1040 return STRING; 1057 return STRING;
1041 } 1058 }
1042 else if (lexWithinMode(L_QUOTED_PRINTABLE)) { 1059 else if (lexWithinMode(L_QUOTED_PRINTABLE)) {
1043 p = lexGetQuotedPrintable(); 1060 p = lexGetQuotedPrintable();
1044 } 1061 }
1045 else { 1062 else {
1046#ifdef _SUPPORT_LINE_FOLDING 1063#ifdef _SUPPORT_LINE_FOLDING
1047 p = lexGet1Value(); 1064 p = lexGet1Value();
1048#else 1065#else
1049 p = lexGetStrUntil(";\n"); 1066 p = lexGetStrUntil(";\n");
1050#endif 1067#endif
1051 } 1068 }
1052 if (p) { 1069 if (p) {
1053 DBG_(("db: STRING: '%s'\n", p)); 1070 DBG_(("db: STRING: '%s'\n", p));
1054 yylval.str = p; 1071 yylval.str = p;
1055 return STRING; 1072 return STRING;
1056 } 1073 }
1057 else return 0; 1074 else return 0;
1058 } 1075 }
1059 } 1076 }
1060 else { 1077 else {
1061 /* normal mode */ 1078 /* normal mode */
1062 while (1) { 1079 while (1) {
1063 int c = lexGetc(); 1080 int c = lexGetc();
1064 switch(c) { 1081 switch(c) {
1065 case ':': { 1082 case ':': {
1066 /* consume all line separator(s) adjacent to each other */ 1083 /* consume all line separator(s) adjacent to each other */
1067 /* ignoring linesep immediately after colon. */ 1084 /* ignoring linesep immediately after colon. */
1085 /* I don't see this in the spec, and it breaks null values -- WA
1068 c = lexLookahead(); 1086 c = lexLookahead();
1069 while (strchr("\n",c)) { 1087 while (strchr("\n",c)) {
1070 lexSkipLookahead(); 1088 lexSkipLookahead();
1071 c = lexLookahead(); 1089 c = lexLookahead();
1072 ++mime_lineNum; 1090 ++mime_lineNum;
1073 } 1091 }
1092 */
1074 DBG_(("db: COLON\n")); 1093 DBG_(("db: COLON\n"));
1075 return COLON; 1094 return COLON;
1076 } 1095 }
1077 case ';': 1096 case ';':
1078 DBG_(("db: SEMICOLON\n")); 1097 DBG_(("db: SEMICOLON\n"));
1079 return SEMICOLON; 1098 return SEMICOLON;
1080 case '=': 1099 case '=':
1081 DBG_(("db: EQ\n")); 1100 DBG_(("db: EQ\n"));
1082 return EQ; 1101 return EQ;
1083 /* ignore whitespace in this mode */ 1102 /* ignore whitespace in this mode */
1084 case '\t': 1103 case '\t':
1085 case ' ': continue; 1104 case ' ': continue;
1086 case '\n': { 1105 case '\n': {
1087 ++mime_lineNum; 1106 ++mime_lineNum;
1088 continue; 1107 continue;
1089 } 1108 }
1090 case EOF: return 0; 1109 case EOF: return 0;
1091 break; 1110 break;
1092 default: { 1111 default: {
1093 lexPushLookaheadc(c); 1112 lexPushLookaheadc(c);
1094 if (isalnum(c)) { 1113 if (isalnum(c)) {
1095 char *t = lexGetWord(); 1114 char *t = lexGetWord();
1096 yylval.str = t; 1115 yylval.str = t;
1097 if (!qstricmp(t, "begin")) { 1116 if (!qstricmp(t, "begin")) {
1098 return match_begin_end_name(0); 1117 return match_begin_end_name(0);
1099 } 1118 }
1100 else if (!qstricmp(t,"end")) { 1119 else if (!qstricmp(t,"end")) {
1101 return match_begin_end_name(1); 1120 return match_begin_end_name(1);
1102 } 1121 }
1103 else { 1122 else {
1104 DBG_(("db: ID '%s'\n", t)); 1123 DBG_(("db: ID '%s'\n", t));
1105 return ID; 1124 return ID;
1106 } 1125 }
1107 } 1126 }
1108 else { 1127 else {
1109 /* unknow token */ 1128 /* unknow token */
1110 return 0; 1129 return 0;
1111 } 1130 }
1112 break; 1131 break;
1113 } 1132 }
1114 } 1133 }
1115 } 1134 }
1116 } 1135 }
1117 return 0; 1136 return 0;
1118 } 1137 }
1119 1138
1120 1139
1121/***************************************************************************/ 1140/***************************************************************************/
1122 /*** Public Functions ****/ 1141 /*** Public Functions ****/
1123/***************************************************************************/ 1142/***************************************************************************/
1124 1143
1125static VObject* Parse_MIMEHelper() 1144static VObject* Parse_MIMEHelper()
1126 { 1145 {
1127 ObjStackTop = -1; 1146 ObjStackTop = -1;
1128 mime_numErrors = 0; 1147 mime_numErrors = 0;
1129 mime_lineNum = 1; 1148 mime_lineNum = 1;
1130 vObjList = 0; 1149 vObjList = 0;
1131 curObj = 0; 1150 curObj = 0;
1132 1151
1133 if (yyparse() != 0) 1152 if (yyparse() != 0)
1134 return 0; 1153 return 0;
1135 1154
1136 finiLex(); 1155 finiLex();
1137 return vObjList; 1156 return vObjList;
1138 } 1157 }
1139 1158
1140/*--------------------------------------------*/ 1159/*--------------------------------------------*/
1141DLLEXPORT(VObject*) Parse_MIME(const char *input, unsigned long len) 1160DLLEXPORT(VObject*) Parse_MIME(const char *input, unsigned long len)
1142 { 1161 {
1143 initLex(input, len, 0); 1162 initLex(input, len, 0);
1144 return Parse_MIMEHelper(); 1163 return Parse_MIMEHelper();
1145 } 1164 }
1146 1165
1147 1166
1148#if INCLUDEMFC 1167#if INCLUDEMFC
1149 1168
1150DLLEXPORT(VObject*) Parse_MIME_FromFile(CFile *file) 1169DLLEXPORT(VObject*) Parse_MIME_FromFile(CFile *file)
1151 { 1170 {
1152 unsigned long startPos; 1171 unsigned long startPos;
1153 VObject *result; 1172 VObject *result;
1154 1173
1155 initLex(0,-1,file); 1174 initLex(0,-1,file);
1156 startPos = file->GetPosition(); 1175 startPos = file->GetPosition();
1157 if (!(result = Parse_MIMEHelper())) 1176 if (!(result = Parse_MIMEHelper()))
1158 file->Seek(startPos, CFile::begin); 1177 file->Seek(startPos, CFile::begin);
1159 return result; 1178 return result;
1160 } 1179 }
1161 1180
1162#else 1181#else
1163 1182
1164VObject* Parse_MIME_FromFile(FILE *file) 1183VObject* Parse_MIME_FromFile(FILE *file)
1165 { 1184 {
1166 VObject *result; 1185 VObject *result;
1167 long startPos; 1186 long startPos;
1168 1187
1169 initLex(0,(unsigned long)-1,file); 1188 initLex(0,(unsigned long)-1,file);
1170 startPos = ftell(file); 1189 startPos = ftell(file);
1171 if (!(result = Parse_MIMEHelper())) { 1190 if (!(result = Parse_MIMEHelper())) {
1172 fseek(file,startPos,SEEK_SET); 1191 fseek(file,startPos,SEEK_SET);
1173 } 1192 }
1174 return result; 1193 return result;
1175 } 1194 }
1176 1195
1177DLLEXPORT(VObject*) Parse_MIME_FromFileName(char *fname) 1196DLLEXPORT(VObject*) Parse_MIME_FromFileName(char *fname)
1178 { 1197 {
1179 FILE *fp = fopen(fname,"r"); 1198 FILE *fp = fopen(fname,"r");
1180 if (fp) { 1199 if (fp) {
1181 VObject* o = Parse_MIME_FromFile(fp); 1200 VObject* o = Parse_MIME_FromFile(fp);
1182 fclose(fp); 1201 fclose(fp);
1183 return o; 1202 return o;
1184 } 1203 }
1185 else { 1204 else {
1186 char msg[80]; 1205 char msg[80];
1187 sprintf(msg, "can't open file '%s' for reading\n", fname); 1206 sprintf(msg, "can't open file '%s' for reading\n", fname);
1188 mime_error_(msg); 1207 mime_error_(msg);
1189 return 0; 1208 return 0;
1190 } 1209 }
1191 } 1210 }
1192 1211
1193#endif 1212#endif
1194 1213
1195/*-------------------------------------*/ 1214/*-------------------------------------*/
1196 1215
1197static MimeErrorHandler mimeErrorHandler; 1216static MimeErrorHandler mimeErrorHandler;
1198 1217
1199DLLEXPORT(void) registerMimeErrorHandler(MimeErrorHandler me) 1218DLLEXPORT(void) registerMimeErrorHandler(MimeErrorHandler me)
1200 { 1219 {
1201 mimeErrorHandler = me; 1220 mimeErrorHandler = me;
1202 } 1221 }
1203 1222
1204void mime_error(char *s) 1223void mime_error(char *s)
1205 { 1224 {
1206 char msg[256]; 1225 char msg[256];
1207 if (mimeErrorHandler) { 1226 if (mimeErrorHandler) {
1208 sprintf(msg,"%s at line %d", s, mime_lineNum); 1227 sprintf(msg,"%s at line %d", s, mime_lineNum);
1209 mimeErrorHandler(msg); 1228 mimeErrorHandler(msg);
1210 } 1229 }
1211 } 1230 }
1212 1231
1213void mime_error_(char *s) 1232void mime_error_(char *s)
1214 { 1233 {
1215 if (mimeErrorHandler) { 1234 if (mimeErrorHandler) {
1216 mimeErrorHandler(s); 1235 mimeErrorHandler(s);
1217 } 1236 }
1218 } 1237 }
1219 1238
1220#line 1221 "y.tab.c" 1239#line 1240 "y.tab.c"
1221#define YYABORT goto yyabort 1240#define YYABORT goto yyabort
1222#define YYREJECT goto yyabort 1241#define YYREJECT goto yyabort
1223#define YYACCEPT goto yyaccept 1242#define YYACCEPT goto yyaccept
1224#define YYERROR goto yyerrlab 1243#define YYERROR goto yyerrlab
1225int 1244int
1226#if defined(__STDC__) 1245#if defined(__STDC__)
1227yyparse(void) 1246yyparse(void)
1228#else 1247#else
1229yyparse() 1248yyparse()
1230#endif 1249#endif
1231{ 1250{
1232 register int yym, yyn, yystate; 1251 register int yym, yyn, yystate;
1233#if YYDEBUG 1252#if YYDEBUG
1234 register char *yys; 1253 register char *yys;
1235 extern char *getenv(); 1254 extern char *getenv();
1236 1255
1237 if (yys = getenv("YYDEBUG")) 1256 if (yys = getenv("YYDEBUG"))
1238 { 1257 {
1239 yyn = *yys; 1258 yyn = *yys;
1240 if (yyn >= '0' && yyn <= '9') 1259 if (yyn >= '0' && yyn <= '9')
1241 yydebug = yyn - '0'; 1260 yydebug = yyn - '0';
1242 } 1261 }
1243#endif 1262#endif
1244 1263
1245 yynerrs = 0; 1264 yynerrs = 0;
1246 yyerrflag = 0; 1265 yyerrflag = 0;
1247 yychar = (-1); 1266 yychar = (-1);
1248 1267
1249 yyssp = yyss; 1268 yyssp = yyss;
1250 yyvsp = yyvs; 1269 yyvsp = yyvs;
1251 *yyssp = yystate = 0; 1270 *yyssp = yystate = 0;
1252 1271
1253yyloop: 1272yyloop:
1254 if ((yyn = yydefred[yystate]) != 0) goto yyreduce; 1273 if ((yyn = yydefred[yystate]) != 0) goto yyreduce;
1255 if (yychar < 0) 1274 if (yychar < 0)
1256 { 1275 {
1257 if ((yychar = yylex()) < 0) yychar = 0; 1276 if ((yychar = yylex()) < 0) yychar = 0;
1258#if YYDEBUG 1277#if YYDEBUG
1259 if (yydebug) 1278 if (yydebug)
1260 { 1279 {
1261 yys = 0; 1280 yys = 0;
1262 if (yychar <= YYMAXTOKEN) yys = yyname[yychar]; 1281 if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
1263 if (!yys) yys = "illegal-symbol"; 1282 if (!yys) yys = "illegal-symbol";
1264 printf("%sdebug: state %d, reading %d (%s)\n", 1283 printf("%sdebug: state %d, reading %d (%s)\n",
1265 YYPREFIX, yystate, yychar, yys); 1284 YYPREFIX, yystate, yychar, yys);
1266 } 1285 }
1267#endif 1286#endif
1268 } 1287 }
1269 if ((yyn = yysindex[yystate]) && (yyn += yychar) >= 0 && 1288 if ((yyn = yysindex[yystate]) && (yyn += yychar) >= 0 &&
1270 yyn <= YYTABLESIZE && yycheck[yyn] == yychar) 1289 yyn <= YYTABLESIZE && yycheck[yyn] == yychar)
1271 { 1290 {
1272#if YYDEBUG 1291#if YYDEBUG
1273 if (yydebug) 1292 if (yydebug)
1274 printf("%sdebug: state %d, shifting to state %d\n", 1293 printf("%sdebug: state %d, shifting to state %d\n",
1275 YYPREFIX, yystate, yytable[yyn]); 1294 YYPREFIX, yystate, yytable[yyn]);
1276#endif 1295#endif
1277 if (yyssp >= yyss + yystacksize - 1) 1296 if (yyssp >= yyss + yystacksize - 1)
1278 { 1297 {
1279 goto yyoverflow; 1298 goto yyoverflow;
1280 } 1299 }
1281 *++yyssp = yystate = yytable[yyn]; 1300 *++yyssp = yystate = yytable[yyn];
1282 *++yyvsp = yylval; 1301 *++yyvsp = yylval;
1283 yychar = (-1); 1302 yychar = (-1);
1284 if (yyerrflag > 0) --yyerrflag; 1303 if (yyerrflag > 0) --yyerrflag;
1285 goto yyloop; 1304 goto yyloop;
1286 } 1305 }
1287 if ((yyn = yyrindex[yystate]) && (yyn += yychar) >= 0 && 1306 if ((yyn = yyrindex[yystate]) && (yyn += yychar) >= 0 &&
1288 yyn <= YYTABLESIZE && yycheck[yyn] == yychar) 1307 yyn <= YYTABLESIZE && yycheck[yyn] == yychar)
1289 { 1308 {
1290 yyn = yytable[yyn]; 1309 yyn = yytable[yyn];
1291 goto yyreduce; 1310 goto yyreduce;
1292 } 1311 }
1293 if (yyerrflag) goto yyinrecovery; 1312 if (yyerrflag) goto yyinrecovery;
1294 yyerror("syntax error"); 1313 yyerror("syntax error");
1295#ifdef lint 1314#ifdef lint
1296 goto yyerrlab; 1315 goto yyerrlab;
1297#endif 1316#endif
1298yyerrlab: 1317yyerrlab:
1299 ++yynerrs; 1318 ++yynerrs;
1300yyinrecovery: 1319yyinrecovery:
1301 if (yyerrflag < 3) 1320 if (yyerrflag < 3)
1302 { 1321 {
1303 yyerrflag = 3; 1322 yyerrflag = 3;
1304 for (;;) 1323 for (;;)
1305 { 1324 {
1306 if ((yyn = yysindex[*yyssp]) && (yyn += YYERRCODE) >= 0 && 1325 if ((yyn = yysindex[*yyssp]) && (yyn += YYERRCODE) >= 0 &&
1307 yyn <= YYTABLESIZE && yycheck[yyn] == YYERRCODE) 1326 yyn <= YYTABLESIZE && yycheck[yyn] == YYERRCODE)
1308 { 1327 {
1309#if YYDEBUG 1328#if YYDEBUG
1310 if (yydebug) 1329 if (yydebug)
1311 printf("%sdebug: state %d, error recovery shifting\ 1330 printf("%sdebug: state %d, error recovery shifting\
1312 to state %d\n", YYPREFIX, *yyssp, yytable[yyn]); 1331 to state %d\n", YYPREFIX, *yyssp, yytable[yyn]);
1313#endif 1332#endif
1314 if (yyssp >= yyss + yystacksize - 1) 1333 if (yyssp >= yyss + yystacksize - 1)
1315 { 1334 {
1316 goto yyoverflow; 1335 goto yyoverflow;
@@ -1424,153 +1443,153 @@ case 21:
1424#line 289 "backend/vcc.y" 1443#line 289 "backend/vcc.y"
1425{ 1444{
1426 enterAttr(yyvsp[0].str,0); 1445 enterAttr(yyvsp[0].str,0);
1427 } 1446 }
1428break; 1447break;
1429case 22: 1448case 22:
1430#line 293 "backend/vcc.y" 1449#line 293 "backend/vcc.y"
1431{ 1450{
1432 enterAttr(yyvsp[-2].str,yyvsp[0].str); 1451 enterAttr(yyvsp[-2].str,yyvsp[0].str);
1433 1452
1434 } 1453 }
1435break; 1454break;
1436case 24: 1455case 24:
1437#line 302 "backend/vcc.y" 1456#line 302 "backend/vcc.y"
1438{ enterValues(yyvsp[-1].str); } 1457{ enterValues(yyvsp[-1].str); }
1439break; 1458break;
1440case 26: 1459case 26:
1441#line 304 "backend/vcc.y" 1460#line 304 "backend/vcc.y"
1442{ enterValues(yyvsp[0].str); } 1461{ enterValues(yyvsp[0].str); }
1443break; 1462break;
1444case 28: 1463case 28:
1445#line 309 "backend/vcc.y" 1464#line 309 "backend/vcc.y"
1446{ yyval.str = 0; } 1465{ yyval.str = 0; }
1447break; 1466break;
1448case 29: 1467case 29:
1449#line 314 "backend/vcc.y" 1468#line 314 "backend/vcc.y"
1450{ if (!pushVObject(VCCalProp)) YYERROR; } 1469{ if (!pushVObject(VCCalProp)) YYERROR; }
1451break; 1470break;
1452case 30: 1471case 30:
1453#line 317 "backend/vcc.y" 1472#line 317 "backend/vcc.y"
1454{ yyval.vobj = popVObject(); } 1473{ yyval.vobj = popVObject(); }
1455break; 1474break;
1456case 31: 1475case 31:
1457#line 319 "backend/vcc.y" 1476#line 319 "backend/vcc.y"
1458{ if (!pushVObject(VCCalProp)) YYERROR; } 1477{ if (!pushVObject(VCCalProp)) YYERROR; }
1459break; 1478break;
1460case 32: 1479case 32:
1461#line 321 "backend/vcc.y" 1480#line 321 "backend/vcc.y"
1462{ yyval.vobj = popVObject(); } 1481{ yyval.vobj = popVObject(); }
1463break; 1482break;
1464case 38: 1483case 38:
1465#line 336 "backend/vcc.y" 1484#line 336 "backend/vcc.y"
1466{ 1485{
1467 lexPushMode(L_VEVENT); 1486 lexPushMode(L_VEVENT);
1468 if (!pushVObject(VCEventProp)) YYERROR; 1487 if (!pushVObject(VCEventProp)) YYERROR;
1469 } 1488 }
1470break; 1489break;
1471case 39: 1490case 39:
1472#line 342 "backend/vcc.y" 1491#line 342 "backend/vcc.y"
1473{ 1492{
1474 lexPopMode(0); 1493 lexPopMode(0);
1475 popVObject(); 1494 popVObject();
1476 } 1495 }
1477break; 1496break;
1478case 40: 1497case 40:
1479#line 347 "backend/vcc.y" 1498#line 347 "backend/vcc.y"
1480{ 1499{
1481 lexPushMode(L_VEVENT); 1500 lexPushMode(L_VEVENT);
1482 if (!pushVObject(VCEventProp)) YYERROR; 1501 if (!pushVObject(VCEventProp)) YYERROR;
1483 } 1502 }
1484break; 1503break;
1485case 41: 1504case 41:
1486#line 352 "backend/vcc.y" 1505#line 352 "backend/vcc.y"
1487{ 1506{
1488 lexPopMode(0); 1507 lexPopMode(0);
1489 popVObject(); 1508 popVObject();
1490 } 1509 }
1491break; 1510break;
1492case 42: 1511case 42:
1493#line 360 "backend/vcc.y" 1512#line 360 "backend/vcc.y"
1494{ 1513{
1495 lexPushMode(L_VTODO); 1514 lexPushMode(L_VTODO);
1496 if (!pushVObject(VCTodoProp)) YYERROR; 1515 if (!pushVObject(VCTodoProp)) YYERROR;
1497 } 1516 }
1498break; 1517break;
1499case 43: 1518case 43:
1500#line 366 "backend/vcc.y" 1519#line 366 "backend/vcc.y"
1501{ 1520{
1502 lexPopMode(0); 1521 lexPopMode(0);
1503 popVObject(); 1522 popVObject();
1504 } 1523 }
1505break; 1524break;
1506case 44: 1525case 44:
1507#line 371 "backend/vcc.y" 1526#line 371 "backend/vcc.y"
1508{ 1527{
1509 lexPushMode(L_VTODO); 1528 lexPushMode(L_VTODO);
1510 if (!pushVObject(VCTodoProp)) YYERROR; 1529 if (!pushVObject(VCTodoProp)) YYERROR;
1511 } 1530 }
1512break; 1531break;
1513case 45: 1532case 45:
1514#line 376 "backend/vcc.y" 1533#line 376 "backend/vcc.y"
1515{ 1534{
1516 lexPopMode(0); 1535 lexPopMode(0);
1517 popVObject(); 1536 popVObject();
1518 } 1537 }
1519break; 1538break;
1520#line 1521 "y.tab.c" 1539#line 1540 "y.tab.c"
1521 } 1540 }
1522 yyssp -= yym; 1541 yyssp -= yym;
1523 yystate = *yyssp; 1542 yystate = *yyssp;
1524 yyvsp -= yym; 1543 yyvsp -= yym;
1525 yym = yylhs[yyn]; 1544 yym = yylhs[yyn];
1526 if (yystate == 0 && yym == 0) 1545 if (yystate == 0 && yym == 0)
1527 { 1546 {
1528#if YYDEBUG 1547#if YYDEBUG
1529 if (yydebug) 1548 if (yydebug)
1530 printf("%sdebug: after reduction, shifting from state 0 to\ 1549 printf("%sdebug: after reduction, shifting from state 0 to\
1531 state %d\n", YYPREFIX, YYFINAL); 1550 state %d\n", YYPREFIX, YYFINAL);
1532#endif 1551#endif
1533 yystate = YYFINAL; 1552 yystate = YYFINAL;
1534 *++yyssp = YYFINAL; 1553 *++yyssp = YYFINAL;
1535 *++yyvsp = yyval; 1554 *++yyvsp = yyval;
1536 if (yychar < 0) 1555 if (yychar < 0)
1537 { 1556 {
1538 if ((yychar = yylex()) < 0) yychar = 0; 1557 if ((yychar = yylex()) < 0) yychar = 0;
1539#if YYDEBUG 1558#if YYDEBUG
1540 if (yydebug) 1559 if (yydebug)
1541 { 1560 {
1542 yys = 0; 1561 yys = 0;
1543 if (yychar <= YYMAXTOKEN) yys = yyname[yychar]; 1562 if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
1544 if (!yys) yys = "illegal-symbol"; 1563 if (!yys) yys = "illegal-symbol";
1545 printf("%sdebug: state %d, reading %d (%s)\n", 1564 printf("%sdebug: state %d, reading %d (%s)\n",
1546 YYPREFIX, YYFINAL, yychar, yys); 1565 YYPREFIX, YYFINAL, yychar, yys);
1547 } 1566 }
1548#endif 1567#endif
1549 } 1568 }
1550 if (yychar == 0) goto yyaccept; 1569 if (yychar == 0) goto yyaccept;
1551 goto yyloop; 1570 goto yyloop;
1552 } 1571 }
1553 if ((yyn = yygindex[yym]) && (yyn += yystate) >= 0 && 1572 if ((yyn = yygindex[yym]) && (yyn += yystate) >= 0 &&
1554 yyn <= YYTABLESIZE && yycheck[yyn] == yystate) 1573 yyn <= YYTABLESIZE && yycheck[yyn] == yystate)
1555 yystate = yytable[yyn]; 1574 yystate = yytable[yyn];
1556 else 1575 else
1557 yystate = yydgoto[yym]; 1576 yystate = yydgoto[yym];
1558#if YYDEBUG 1577#if YYDEBUG
1559 if (yydebug) 1578 if (yydebug)
1560 printf("%sdebug: after reduction, shifting from state %d \ 1579 printf("%sdebug: after reduction, shifting from state %d \
1561to state %d\n", YYPREFIX, *yyssp, yystate); 1580to state %d\n", YYPREFIX, *yyssp, yystate);
1562#endif 1581#endif
1563 if (yyssp >= yyss + yystacksize - 1) 1582 if (yyssp >= yyss + yystacksize - 1)
1564 { 1583 {
1565 goto yyoverflow; 1584 goto yyoverflow;
1566 } 1585 }
1567 *++yyssp = yystate; 1586 *++yyssp = yystate;
1568 *++yyvsp = yyval; 1587 *++yyvsp = yyval;
1569 goto yyloop; 1588 goto yyloop;
1570yyoverflow: 1589yyoverflow:
1571 yyerror("yacc stack overflow"); 1590 yyerror("yacc stack overflow");
1572yyabort: 1591yyabort:
1573 return (1); 1592 return (1);
1574yyaccept: 1593yyaccept:
1575 return (0); 1594 return (0);
1576} 1595}
diff --git a/library/backend/vobject.cpp b/library/backend/vobject.cpp
index 2c5b577..b6d17dc 100644
--- a/library/backend/vobject.cpp
+++ b/library/backend/vobject.cpp
@@ -1,185 +1,190 @@
1/*************************************************************************** 1/***************************************************************************
2(C) Copyright 1996 Apple Computer, Inc., AT&T Corp., International 2(C) Copyright 1996 Apple Computer, Inc., AT&T Corp., International
3Business Machines Corporation and Siemens Rolm Communications Inc. 3Business Machines Corporation and Siemens Rolm Communications Inc.
4 4
5For purposes of this license notice, the term Licensors shall mean, 5For purposes of this license notice, the term Licensors shall mean,
6collectively, Apple Computer, Inc., AT&T Corp., International 6collectively, Apple Computer, Inc., AT&T Corp., International
7Business Machines Corporation and Siemens Rolm Communications Inc. 7Business Machines Corporation and Siemens Rolm Communications Inc.
8The term Licensor shall mean any of the Licensors. 8The term Licensor shall mean any of the Licensors.
9 9
10Subject to acceptance of the following conditions, permission is hereby 10Subject to acceptance of the following conditions, permission is hereby
11granted by Licensors without the need for written agreement and without 11granted by Licensors without the need for written agreement and without
12license or royalty fees, to use, copy, modify and distribute this 12license or royalty fees, to use, copy, modify and distribute this
13software for any purpose. 13software for any purpose.
14 14
15The above copyright notice and the following four paragraphs must be 15The above copyright notice and the following four paragraphs must be
16reproduced in all copies of this software and any software including 16reproduced in all copies of this software and any software including
17this software. 17this software.
18 18
19THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS AND NO LICENSOR SHALL HAVE 19THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS AND NO LICENSOR SHALL HAVE
20ANY OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS OR 20ANY OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS OR
21MODIFICATIONS. 21MODIFICATIONS.
22 22
23IN NO EVENT SHALL ANY LICENSOR BE LIABLE TO ANY PARTY FOR DIRECT, 23IN NO EVENT SHALL ANY LICENSOR BE LIABLE TO ANY PARTY FOR DIRECT,
24INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES OR LOST PROFITS ARISING OUT 24INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES OR LOST PROFITS ARISING OUT
25OF THE USE OF THIS SOFTWARE EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 25OF THE USE OF THIS SOFTWARE EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
26DAMAGE. 26DAMAGE.
27 27
28EACH LICENSOR SPECIFICALLY DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, 28EACH LICENSOR SPECIFICALLY DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED,
29INCLUDING BUT NOT LIMITED TO ANY WARRANTY OF NONINFRINGEMENT OR THE 29INCLUDING BUT NOT LIMITED TO ANY WARRANTY OF NONINFRINGEMENT OR THE
30IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 30IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
31PURPOSE. 31PURPOSE.
32 32
33The software is provided with RESTRICTED RIGHTS. Use, duplication, or 33The software is provided with RESTRICTED RIGHTS. Use, duplication, or
34disclosure by the government are subject to restrictions set forth in 34disclosure by the government are subject to restrictions set forth in
35DFARS 252.227-7013 or 48 CFR 52.227-19, as applicable. 35DFARS 252.227-7013 or 48 CFR 52.227-19, as applicable.
36 36
37***************************************************************************/ 37***************************************************************************/
38 38
39/* 39/*
40 * src: vobject.c 40 * src: vobject.c
41 * doc: vobject and APIs to construct vobject, APIs pretty print 41 * doc: vobject and APIs to construct vobject, APIs pretty print
42 * vobject, and convert a vobject into its textual representation. 42 * vobject, and convert a vobject into its textual representation.
43 */ 43 */
44 44
45 #ifndef MWERKS 45 #ifndef MWERKS
46#include <malloc.h> 46#include <malloc.h>
47#endif 47#endif
48 48
49#include <qtopia/private/vobject_p.h> 49#include <qtopia/config.h>
50#include <qtopia/private/qfiledirect_p.h> 50#include "vobject_p.h"
51#include "qfiledirect_p.h"
51#include <string.h> 52#include <string.h>
52#include <stdio.h> 53#include <stdio.h>
53#include <fcntl.h> 54#include <fcntl.h>
54//#include <io.h> 55//#include <io.h>
55 56
56 57
57 #define NAME_OF(o) o->id 58 #define NAME_OF(o) o->id
58 #define VALUE_TYPE(o) o->valType 59 #define VALUE_TYPE(o) o->valType
59 #define STRINGZ_VALUE_OF(o) o->val.strs 60 #define STRINGZ_VALUE_OF(o) o->val.strs
60 #define INTEGER_VALUE_OF(o) o->val.i 61 #define INTEGER_VALUE_OF(o) o->val.i
61 #define LONG_VALUE_OF(o) o->val.l 62 #define LONG_VALUE_OF(o) o->val.l
62 #define ANY_VALUE_OF(o) o->val.any 63 #define ANY_VALUE_OF(o) o->val.any
63 #define VOBJECT_VALUE_OF(o) o->val.vobj 64 #define VOBJECT_VALUE_OF(o) o->val.vobj
64 65
66static char vobj_cs[10];
67static enum { EightBit, QuotedPrintable, Base64 } vobj_enc=EightBit;
68static const char *vobj_enc_s=0;
69
65typedef union ValueItem { 70typedef union ValueItem {
66 const char *strs; 71 const char *strs;
67 unsigned int i; 72 unsigned int i;
68 unsigned long l; 73 unsigned long l;
69 void *any; 74 void *any;
70 VObject *vobj; 75 VObject *vobj;
71 } ValueItem; 76 } ValueItem;
72 77
73struct VObject { 78struct VObject {
74 VObject *next; 79 VObject *next;
75 const char *id; 80 const char *id;
76 VObject *prop; 81 VObject *prop;
77 unsigned short valType; 82 unsigned short valType;
78 ValueItem val; 83 ValueItem val;
79 }; 84 };
80 85
81typedef struct StrItem StrItem; 86typedef struct StrItem StrItem;
82 87
83struct StrItem { 88struct StrItem {
84 StrItem *next; 89 StrItem *next;
85 const char *s; 90 const char *s;
86 unsigned int refCnt; 91 unsigned int refCnt;
87 }; 92 };
88 93
89const char** fieldedProp; 94DLLEXPORT(const char**) fieldedProp;
90 95
91 96
92 97
93/*---------------------------------------------------------------------- 98/*----------------------------------------------------------------------
94 The following functions involve with memory allocation: 99 The following functions involve with memory allocation:
95 newVObject 100 newVObject
96 deleteVObject 101 deleteVObject
97 dupStr 102 dupStr
98 deleteStr 103 deleteStr
99 newStrItem 104 newStrItem
100 deleteStrItem 105 deleteStrItem
101 ----------------------------------------------------------------------*/ 106 ----------------------------------------------------------------------*/
102 107
103DLLEXPORT(VObject*) newVObject_(const char *id) 108DLLEXPORT(VObject*) newVObject_(const char *id)
104{ 109{
105 VObject *p = (VObject*)malloc(sizeof(VObject)); 110 VObject *p = (VObject*)malloc(sizeof(VObject));
106 p->next = 0; 111 p->next = 0;
107 p->id = id; 112 p->id = id;
108 p->prop = 0; 113 p->prop = 0;
109 VALUE_TYPE(p) = 0; 114 VALUE_TYPE(p) = 0;
110 ANY_VALUE_OF(p) = 0; 115 ANY_VALUE_OF(p) = 0;
111 return p; 116 return p;
112} 117}
113 118
114DLLEXPORT(VObject*) newVObject(const char *id) 119DLLEXPORT(VObject*) newVObject(const char *id)
115{ 120{
116 return newVObject_(lookupStr(id)); 121 return newVObject_(lookupStr(id));
117} 122}
118 123
119DLLEXPORT(void) deleteVObject(VObject *p) 124DLLEXPORT(void) deleteVObject(VObject *p)
120{ 125{
121 unUseStr(p->id); 126 unUseStr(p->id);
122 free(p); 127 free(p);
123} 128}
124 129
125DLLEXPORT(char*) dupStr(const char *s, unsigned int size) 130DLLEXPORT(char*) dupStr(const char *s, unsigned int size)
126{ 131{
127 char *t; 132 char *t;
128 if (size == 0) { 133 if (size == 0) {
129 size = strlen(s); 134 size = strlen(s);
130 } 135 }
131 t = (char*)malloc(size+1); 136 t = (char*)malloc(size+1);
132 if (t) { 137 if (t) {
133 memcpy(t,s,size); 138 memcpy(t,s,size);
134 t[size] = 0; 139 t[size] = 0;
135 return t; 140 return t;
136 } 141 }
137 else { 142 else {
138 return (char*)0; 143 return (char*)0;
139 } 144 }
140} 145}
141 146
142DLLEXPORT(void) deleteStr(const char *p) 147DLLEXPORT(void) deleteStr(const char *p)
143{ 148{
144 if (p) free((void*)p); 149 if (p) free((void*)p);
145} 150}
146 151
147 152
148static StrItem* newStrItem(const char *s, StrItem *next) 153static StrItem* newStrItem(const char *s, StrItem *next)
149{ 154{
150 StrItem *p = (StrItem*)malloc(sizeof(StrItem)); 155 StrItem *p = (StrItem*)malloc(sizeof(StrItem));
151 p->next = next; 156 p->next = next;
152 p->s = s; 157 p->s = s;
153 p->refCnt = 1; 158 p->refCnt = 1;
154 return p; 159 return p;
155} 160}
156 161
157static void deleteStrItem(StrItem *p) 162static void deleteStrItem(StrItem *p)
158{ 163{
159 free((void*)p); 164 free((void*)p);
160} 165}
161 166
162 167
163/*---------------------------------------------------------------------- 168/*----------------------------------------------------------------------
164 The following function provide accesses to VObject's value. 169 The following function provide accesses to VObject's value.
165 ----------------------------------------------------------------------*/ 170 ----------------------------------------------------------------------*/
166 171
167DLLEXPORT(const char*) vObjectName(VObject *o) 172DLLEXPORT(const char*) vObjectName(VObject *o)
168{ 173{
169 return NAME_OF(o); 174 return NAME_OF(o);
170} 175}
171 176
172DLLEXPORT(void) setVObjectName(VObject *o, const char* id) 177DLLEXPORT(void) setVObjectName(VObject *o, const char* id)
173{ 178{
174 NAME_OF(o) = id; 179 NAME_OF(o) = id;
175} 180}
176 181
177DLLEXPORT(const char*) vObjectStringZValue(VObject *o) 182DLLEXPORT(const char*) vObjectStringZValue(VObject *o)
178{ 183{
179 return STRINGZ_VALUE_OF(o); 184 return STRINGZ_VALUE_OF(o);
180} 185}
181 186
182DLLEXPORT(void) setVObjectStringZValue(VObject *o, const char *s) 187DLLEXPORT(void) setVObjectStringZValue(VObject *o, const char *s)
183{ 188{
184 STRINGZ_VALUE_OF(o) = dupStr(s,0); 189 STRINGZ_VALUE_OF(o) = dupStr(s,0);
185 VALUE_TYPE(o) = VCVT_STRINGZ; 190 VALUE_TYPE(o) = VCVT_STRINGZ;
@@ -234,269 +239,269 @@ DLLEXPORT(void) setVObjectVObjectValue(VObject *o, VObject *p)
234 VOBJECT_VALUE_OF(o) = p; 239 VOBJECT_VALUE_OF(o) = p;
235 VALUE_TYPE(o) = VCVT_VOBJECT; 240 VALUE_TYPE(o) = VCVT_VOBJECT;
236} 241}
237 242
238DLLEXPORT(int) vObjectValueType(VObject *o) 243DLLEXPORT(int) vObjectValueType(VObject *o)
239{ 244{
240 return VALUE_TYPE(o); 245 return VALUE_TYPE(o);
241} 246}
242 247
243 248
244/*---------------------------------------------------------------------- 249/*----------------------------------------------------------------------
245 The following functions can be used to build VObject. 250 The following functions can be used to build VObject.
246 ----------------------------------------------------------------------*/ 251 ----------------------------------------------------------------------*/
247 252
248DLLEXPORT(VObject*) addVObjectProp(VObject *o, VObject *p) 253DLLEXPORT(VObject*) addVObjectProp(VObject *o, VObject *p)
249{ 254{
250 /* circular link list pointed to tail */ 255 /* circular link list pointed to tail */
251 /* 256 /*
252 o {next,id,prop,val} 257 o {next,id,prop,val}
253 V 258 V
254 pn {next,id,prop,val} 259 pn {next,id,prop,val}
255 V 260 V
256 ... 261 ...
257 p1 {next,id,prop,val} 262 p1 {next,id,prop,val}
258 V 263 V
259 pn 264 pn
260 --> 265 -->
261 o {next,id,prop,val} 266 o {next,id,prop,val}
262 V 267 V
263 pn {next,id,prop,val} 268 pn {next,id,prop,val}
264 V 269 V
265 p {next,id,prop,val} 270 p {next,id,prop,val}
266 ... 271 ...
267 p1 {next,id,prop,val} 272 p1 {next,id,prop,val}
268 V 273 V
269 pn 274 pn
270 */ 275 */
271 276
272 VObject *tail = o->prop; 277 VObject *tail = o->prop;
273 if (tail) { 278 if (tail) {
274 p->next = tail->next; 279 p->next = tail->next;
275 o->prop = tail->next = p; 280 o->prop = tail->next = p;
276 } 281 }
277 else { 282 else {
278 o->prop = p->next = p; 283 o->prop = p->next = p;
279 } 284 }
280 return p; 285 return p;
281} 286}
282 287
283DLLEXPORT(VObject*) addProp(VObject *o, const char *id) 288DLLEXPORT(VObject*) addProp(VObject *o, const char *id)
284{ 289{
285 return addVObjectProp(o,newVObject(id)); 290 return addVObjectProp(o,newVObject(id));
286} 291}
287 292
288DLLEXPORT(VObject*) addProp_(VObject *o, const char *id) 293DLLEXPORT(VObject*) addProp_(VObject *o, const char *id)
289{ 294{
290 return addVObjectProp(o,newVObject_(id)); 295 return addVObjectProp(o,newVObject_(id));
291} 296}
292 297
293DLLEXPORT(void) addList(VObject **o, VObject *p) 298DLLEXPORT(void) addList(VObject **o, VObject *p)
294{ 299{
295 p->next = 0; 300 p->next = 0;
296 if (*o == 0) { 301 if (*o == 0) {
297 *o = p; 302 *o = p;
298 } 303 }
299 else { 304 else {
300 VObject *t = *o; 305 VObject *t = *o;
301 while (t->next) { 306 while (t->next) {
302 t = t->next; 307 t = t->next;
303 } 308 }
304 t->next = p; 309 t->next = p;
305 } 310 }
306} 311}
307 312
308DLLEXPORT(VObject*) nextVObjectInList(VObject *o) 313DLLEXPORT(VObject*) nextVObjectInList(VObject *o)
309{ 314{
310 return o->next; 315 return o->next;
311} 316}
312 317
313DLLEXPORT(VObject*) setValueWithSize_(VObject *prop, void *val, unsigned int size) 318DLLEXPORT(VObject*) setValueWithSize_(VObject *prop, void *val, unsigned int size)
314{ 319{
315 VObject *sizeProp; 320 VObject *sizeProp;
316 setVObjectAnyValue(prop, val); 321 setVObjectAnyValue(prop, val);
317 sizeProp = addProp(prop,VCDataSizeProp); 322 sizeProp = addProp(prop,VCDataSizeProp);
318 setVObjectLongValue(sizeProp, size); 323 setVObjectLongValue(sizeProp, size);
319 return prop; 324 return prop;
320} 325}
321 326
322DLLEXPORT(VObject*) setValueWithSize(VObject *prop, void *val, unsigned int size) 327DLLEXPORT(VObject*) setValueWithSize(VObject *prop, void *val, unsigned int size)
323{ 328{
324 void *p = dupStr((const char *)val,size); 329 void *p = dupStr((const char *)val,size);
325 return setValueWithSize_(prop,p,p?size:0); 330 return setValueWithSize_(prop,p,p?size:0);
326} 331}
327 332
328DLLEXPORT(void) initPropIterator(VObjectIterator *i, VObject *o) 333DLLEXPORT(void) initPropIterator(VObjectIterator *i, VObject *o)
329{ 334{
330 i->start = o->prop; 335 i->start = o->prop;
331 i->next = 0; 336 i->next = 0;
332} 337}
333 338
334DLLEXPORT(void) initVObjectIterator(VObjectIterator *i, VObject *o) 339DLLEXPORT(void) initVObjectIterator(VObjectIterator *i, VObject *o)
335{ 340{
336 i->start = o->next; 341 i->start = o->next;
337 i->next = 0; 342 i->next = 0;
338} 343}
339 344
340DLLEXPORT(int) moreIteration(VObjectIterator *i) 345DLLEXPORT(int) moreIteration(VObjectIterator *i)
341{ 346{
342 return (i->start && (i->next==0 || i->next!=i->start)); 347 return (i->start && (i->next==0 || i->next!=i->start));
343} 348}
344 349
345DLLEXPORT(VObject*) nextVObject(VObjectIterator *i) 350DLLEXPORT(VObject*) nextVObject(VObjectIterator *i)
346{ 351{
347 if (i->start && i->next != i->start) { 352 if (i->start && i->next != i->start) {
348 if (i->next == 0) { 353 if (i->next == 0) {
349 i->next = i->start->next; 354 i->next = i->start->next;
350 return i->next; 355 return i->next;
351 } 356 }
352 else { 357 else {
353 i->next = i->next->next; 358 i->next = i->next->next;
354 return i->next; 359 return i->next;
355 } 360 }
356 } 361 }
357 else return (VObject*)0; 362 else return (VObject*)0;
358} 363}
359 364
360DLLEXPORT(VObject*) isAPropertyOf(VObject *o, const char *id) 365DLLEXPORT(VObject*) isAPropertyOf(VObject *o, const char *id)
361{ 366{
362 VObjectIterator i; 367 VObjectIterator i;
363 initPropIterator(&i,o); 368 initPropIterator(&i,o);
364 while (moreIteration(&i)) { 369 while (moreIteration(&i)) {
365 VObject *each = nextVObject(&i); 370 VObject *each = nextVObject(&i);
366 if (!qstricmp(id,each->id)) 371 if (!qstricmp(id,each->id))
367 return each; 372 return each;
368 } 373 }
369 return (VObject*)0; 374 return (VObject*)0;
370} 375}
371 376
372DLLEXPORT(VObject*) addGroup(VObject *o, const char *g) 377DLLEXPORT(VObject*) addGroup(VObject *o, const char *g)
373{ 378{
374 /* 379 /*
375 a.b.c 380 a.b.c
376 --> 381 -->
377 prop(c) 382 prop(c)
378 prop(VCGrouping=b) 383 prop(VCGrouping=b)
379 prop(VCGrouping=a) 384 prop(VCGrouping=a)
380 */ 385 */
381 char *dot = strrchr(g,'.'); 386 char *dot = strrchr(g,'.');
382 if (dot) { 387 if (dot) {
383 VObject *p, *t; 388 VObject *p, *t;
384 char *gs, *n = dot+1; 389 char *gs, *n = dot+1;
385 gs = dupStr(g,0);/* so we can write to it. */ 390 gs = dupStr(g,0);/* so we can write to it. */
386 /* used to be 391 /* used to be
387 * t = p = addProp_(o,lookupProp_(n)); 392 * t = p = addProp_(o,lookupProp_(n));
388 */ 393 */
389 t = p = addProp_(o,lookupProp(n)); 394 t = p = addProp_(o,lookupProp(n));
390 dot = strrchr(gs,'.'); 395 dot = strrchr(gs,'.');
391 *dot = 0; 396 *dot = 0;
392 do { 397 do {
393 dot = strrchr(gs,'.'); 398 dot = strrchr(gs,'.');
394 if (dot) { 399 if (dot) {
395 n = dot+1; 400 n = dot+1;
396 *dot=0; 401 *dot=0;
397 } 402 }
398 else 403 else
399 n = gs; 404 n = gs;
400 /* property(VCGroupingProp=n); 405 /* property(VCGroupingProp=n);
401 *and the value may have VCGrouping property 406 *and the value may have VCGrouping property
402 */ 407 */
403 t = addProp(t,VCGroupingProp); 408 t = addProp(t,VCGroupingProp);
404 setVObjectStringZValue(t,lookupProp_(n)); 409 setVObjectStringZValue(t,lookupProp_(n));
405 } while (n != gs); 410 } while (n != gs);
406 deleteStr(gs); 411 deleteStr(gs);
407 return p; 412 return p;
408 } 413 }
409 else 414 else
410 return addProp_(o,lookupProp(g)); 415 return addProp_(o,lookupProp(g));
411} 416}
412 417
413DLLEXPORT(VObject*) addPropValue(VObject *o, const char *p, const char *v) 418DLLEXPORT(VObject*) addPropValue(VObject *o, const char *p, const char *v)
414{ 419{
415 VObject *prop; 420 VObject *prop;
416 prop = addProp(o,p); 421 prop = addProp(o,p);
417 setVObjectStringZValue_(prop, strdup( v ) ); 422 setVObjectStringZValue_(prop, strdup( v ) );
418 return prop; 423 return prop;
419} 424}
420 425
421DLLEXPORT(VObject*) addPropSizedValue_(VObject *o, const char *p, const char *v, 426DLLEXPORT(VObject*) addPropSizedValue_(VObject *o, const char *p, const char *v,
422 unsigned int size) 427 unsigned int size)
423{ 428{
424 VObject *prop; 429 VObject *prop;
425 prop = addProp(o,p); 430 prop = addProp(o,p);
426 setValueWithSize_(prop, (void*)v, size); 431 setValueWithSize_(prop, (void*)v, size);
427 return prop; 432 return prop;
428} 433}
429 434
430DLLEXPORT(VObject*) addPropSizedValue(VObject *o, const char *p, const char *v, 435DLLEXPORT(VObject*) addPropSizedValue(VObject *o, const char *p, const char *v,
431 unsigned int size) 436 unsigned int size)
432{ 437{
433 return addPropSizedValue_(o,p,dupStr(v,size),size); 438 return addPropSizedValue_(o,p,dupStr(v,size),size);
434} 439}
435 440
436 441
437DLLEXPORT(void) cleanVObject(VObject *o) 442DLLEXPORT(void) cleanVObject(VObject *o)
438{ 443{
439 if (o == 0) return; 444 if (o == 0) return;
440 if (o->prop) { 445 if (o->prop) {
441 /* destroy time: cannot use the iterator here. 446 /* destroy time: cannot use the iterator here.
442 Have to break the cycle in the circular link 447 Have to break the cycle in the circular link
443 list and turns it into regular NULL-terminated 448 list and turns it into regular NULL-terminated
444 list -- since at some point of destruction, 449 list -- since at some point of destruction,
445 the reference entry for the iterator to work 450 the reference entry for the iterator to work
446 will not longer be valid. 451 will not longer be valid.
447 */ 452 */
448 VObject *p; 453 VObject *p;
449 p = o->prop->next; 454 p = o->prop->next;
450 o->prop->next = 0; 455 o->prop->next = 0;
451 do { 456 do {
452 VObject *t = p->next; 457 VObject *t = p->next;
453 cleanVObject(p); 458 cleanVObject(p);
454 p = t; 459 p = t;
455 } while (p); 460 } while (p);
456 } 461 }
457 switch (VALUE_TYPE(o)) { 462 switch (VALUE_TYPE(o)) {
458 case VCVT_STRINGZ: 463 case VCVT_STRINGZ:
459 case VCVT_RAW: 464 case VCVT_RAW:
460 // assume they are all allocated by malloc. 465 // assume they are all allocated by malloc.
461 free((char*)STRINGZ_VALUE_OF(o)); 466 free((char*)STRINGZ_VALUE_OF(o));
462 break; 467 break;
463 case VCVT_VOBJECT: 468 case VCVT_VOBJECT:
464 cleanVObject(VOBJECT_VALUE_OF(o)); 469 cleanVObject(VOBJECT_VALUE_OF(o));
465 break; 470 break;
466 } 471 }
467 deleteVObject(o); 472 deleteVObject(o);
468} 473}
469 474
470DLLEXPORT(void) cleanVObjects(VObject *list) 475DLLEXPORT(void) cleanVObjects(VObject *list)
471{ 476{
472 while (list) { 477 while (list) {
473 VObject *t = list; 478 VObject *t = list;
474 list = nextVObjectInList(list); 479 list = nextVObjectInList(list);
475 cleanVObject(t); 480 cleanVObject(t);
476 } 481 }
477} 482}
478 483
479/*---------------------------------------------------------------------- 484/*----------------------------------------------------------------------
480 The following is a String Table Facilities. 485 The following is a String Table Facilities.
481 ----------------------------------------------------------------------*/ 486 ----------------------------------------------------------------------*/
482 487
483#define STRTBLSIZE 255 488#define STRTBLSIZE 255
484 489
485static StrItem *strTbl[STRTBLSIZE]; 490static StrItem *strTbl[STRTBLSIZE];
486 491
487static unsigned int hashStr(const char *s) 492static unsigned int hashStr(const char *s)
488{ 493{
489 unsigned int h = 0; 494 unsigned int h = 0;
490 int i; 495 int i;
491 for (i=0;s[i];i++) { 496 for (i=0;s[i];i++) {
492 h += s[i]*i; 497 h += s[i]*i;
493 } 498 }
494 return h % STRTBLSIZE; 499 return h % STRTBLSIZE;
495} 500}
496 501
497DLLEXPORT(const char*) lookupStr(const char *s) 502DLLEXPORT(const char*) lookupStr(const char *s)
498{ 503{
499 StrItem *t; 504 StrItem *t;
500 unsigned int h = hashStr(s); 505 unsigned int h = hashStr(s);
501 if ((t = strTbl[h]) != 0) { 506 if ((t = strTbl[h]) != 0) {
502 do { 507 do {
@@ -706,641 +711,655 @@ static struct PreDefProp propNames[] = {
706 { VCISDNProp, 0, 0, 0 }, 711 { VCISDNProp, 0, 0, 0 },
707 { VCJPEGProp, 0, 0, 0 }, 712 { VCJPEGProp, 0, 0, 0 },
708 { VCLanguageProp, 0, 0, 0 }, 713 { VCLanguageProp, 0, 0, 0 },
709 { VCLastModifiedProp, 0, 0, 0 }, 714 { VCLastModifiedProp, 0, 0, 0 },
710 { VCLastRevisedProp, 0, 0, 0 }, 715 { VCLastRevisedProp, 0, 0, 0 },
711 { VCLocationProp, 0, 0, 0 }, 716 { VCLocationProp, 0, 0, 0 },
712 { VCLogoProp, 0, 0, 0 }, 717 { VCLogoProp, 0, 0, 0 },
713 { VCMailerProp, 0, 0, 0 }, 718 { VCMailerProp, 0, 0, 0 },
714 { VCMAlarmProp, 0, MAlarmFields, 0 }, 719 { VCMAlarmProp, 0, MAlarmFields, 0 },
715 { VCMCIMailProp, 0, 0, 0 }, 720 { VCMCIMailProp, 0, 0, 0 },
716 { VCMessageProp, 0, 0, 0 }, 721 { VCMessageProp, 0, 0, 0 },
717 { VCMETProp, 0, 0, 0 }, 722 { VCMETProp, 0, 0, 0 },
718 { VCModemProp, 0, 0, 0 }, 723 { VCModemProp, 0, 0, 0 },
719 { VCMPEG2Prop, 0, 0, 0 }, 724 { VCMPEG2Prop, 0, 0, 0 },
720 { VCMPEGProp, 0, 0, 0 }, 725 { VCMPEGProp, 0, 0, 0 },
721 { VCMSNProp, 0, 0, 0 }, 726 { VCMSNProp, 0, 0, 0 },
722 { VCNamePrefixesProp, 0, 0, 0 }, 727 { VCNamePrefixesProp, 0, 0, 0 },
723 { VCNameProp, 0, nameFields, 0 }, 728 { VCNameProp, 0, nameFields, 0 },
724 { VCNameSuffixesProp, 0, 0, 0 }, 729 { VCNameSuffixesProp, 0, 0, 0 },
725 { VCNoteProp, 0, 0, 0 }, 730 { VCNoteProp, 0, 0, 0 },
726 { VCOrgNameProp, 0, 0, 0 }, 731 { VCOrgNameProp, 0, 0, 0 },
727 { VCOrgProp, 0, orgFields, 0 }, 732 { VCOrgProp, 0, orgFields, 0 },
728 { VCOrgUnit2Prop, 0, 0, 0 }, 733 { VCOrgUnit2Prop, 0, 0, 0 },
729 { VCOrgUnit3Prop, 0, 0, 0 }, 734 { VCOrgUnit3Prop, 0, 0, 0 },
730 { VCOrgUnit4Prop, 0, 0, 0 }, 735 { VCOrgUnit4Prop, 0, 0, 0 },
731 { VCOrgUnitProp, 0, 0, 0 }, 736 { VCOrgUnitProp, 0, 0, 0 },
732 { VCPagerProp, 0, 0, 0 }, 737 { VCPagerProp, 0, 0, 0 },
733 { VCPAlarmProp, 0, PAlarmFields, 0 }, 738 { VCPAlarmProp, 0, PAlarmFields, 0 },
734 { VCParcelProp, 0, 0, 0 }, 739 { VCParcelProp, 0, 0, 0 },
735 { VCPartProp, 0, 0, 0 }, 740 { VCPartProp, 0, 0, 0 },
736 { VCPCMProp, 0, 0, 0 }, 741 { VCPCMProp, 0, 0, 0 },
737 { VCPDFProp, 0, 0, 0 }, 742 { VCPDFProp, 0, 0, 0 },
738 { VCPGPProp, 0, 0, 0 }, 743 { VCPGPProp, 0, 0, 0 },
739 { VCPhotoProp, 0, 0, 0 }, 744 { VCPhotoProp, 0, 0, 0 },
740 { VCPICTProp, 0, 0, 0 }, 745 { VCPICTProp, 0, 0, 0 },
741 { VCPMBProp, 0, 0, 0 }, 746 { VCPMBProp, 0, 0, 0 },
742 { VCPostalBoxProp, 0, 0, 0 }, 747 { VCPostalBoxProp, 0, 0, 0 },
743 { VCPostalCodeProp, 0, 0, 0 }, 748 { VCPostalCodeProp, 0, 0, 0 },
744 { VCPostalProp, 0, 0, 0 }, 749 { VCPostalProp, 0, 0, 0 },
745 { VCPowerShareProp, 0, 0, 0 }, 750 { VCPowerShareProp, 0, 0, 0 },
746 { VCPreferredProp, 0, 0, 0 }, 751 { VCPreferredProp, 0, 0, 0 },
747 { VCPriorityProp, 0, 0, 0 }, 752 { VCPriorityProp, 0, 0, 0 },
748 { VCProcedureNameProp, 0, 0, 0 }, 753 { VCProcedureNameProp, 0, 0, 0 },
749 { VCProdIdProp, 0, 0, 0 }, 754 { VCProdIdProp, 0, 0, 0 },
750 { VCProdigyProp, 0, 0, 0 }, 755 { VCProdigyProp, 0, 0, 0 },
751 { VCPronunciationProp, 0, 0, 0 }, 756 { VCPronunciationProp, 0, 0, 0 },
752 { VCPSProp, 0, 0, 0 }, 757 { VCPSProp, 0, 0, 0 },
753 { VCPublicKeyProp, 0, 0, 0 }, 758 { VCPublicKeyProp, 0, 0, 0 },
754 { VCQPProp, VCQuotedPrintableProp, 0, 0 }, 759 { VCQPProp, VCQuotedPrintableProp, 0, 0 },
755 { VCQuickTimeProp, 0, 0, 0 }, 760 { VCQuickTimeProp, 0, 0, 0 },
756 { VCQuotedPrintableProp, 0, 0, 0 }, 761 { VCQuotedPrintableProp, 0, 0, 0 },
757 { VCRDateProp, 0, 0, 0 }, 762 { VCRDateProp, 0, 0, 0 },
758 { VCRegionProp, 0, 0, 0 }, 763 { VCRegionProp, 0, 0, 0 },
759 { VCRelatedToProp, 0, 0, 0 }, 764 { VCRelatedToProp, 0, 0, 0 },
760 { VCRepeatCountProp, 0, 0, 0 }, 765 { VCRepeatCountProp, 0, 0, 0 },
761 { VCResourcesProp, 0, 0, 0 }, 766 { VCResourcesProp, 0, 0, 0 },
762 { VCRNumProp, 0, 0, 0 }, 767 { VCRNumProp, 0, 0, 0 },
763 { VCRoleProp, 0, 0, 0 }, 768 { VCRoleProp, 0, 0, 0 },
764 { VCRRuleProp, 0, 0, 0 }, 769 { VCRRuleProp, 0, 0, 0 },
765 { VCRSVPProp, 0, 0, 0 }, 770 { VCRSVPProp, 0, 0, 0 },
766 { VCRunTimeProp, 0, 0, 0 }, 771 { VCRunTimeProp, 0, 0, 0 },
767 { VCSequenceProp, 0, 0, 0 }, 772 { VCSequenceProp, 0, 0, 0 },
768 { VCSnoozeTimeProp, 0, 0, 0 }, 773 { VCSnoozeTimeProp, 0, 0, 0 },
769 { VCStartProp, 0, 0, 0 }, 774 { VCStartProp, 0, 0, 0 },
770 { VCStatusProp, 0, 0, 0 }, 775 { VCStatusProp, 0, 0, 0 },
771 { VCStreetAddressProp, 0, 0, 0 }, 776 { VCStreetAddressProp, 0, 0, 0 },
772 { VCSubTypeProp, 0, 0, 0 }, 777 { VCSubTypeProp, 0, 0, 0 },
773 { VCSummaryProp, 0, 0, 0 }, 778 { VCSummaryProp, 0, 0, 0 },
774 { VCTelephoneProp, 0, 0, 0 }, 779 { VCTelephoneProp, 0, 0, 0 },
775 { VCTIFFProp, 0, 0, 0 }, 780 { VCTIFFProp, 0, 0, 0 },
776 { VCTimeZoneProp, 0, 0, 0 }, 781 { VCTimeZoneProp, 0, 0, 0 },
777 { VCTitleProp, 0, 0, 0 }, 782 { VCTitleProp, 0, 0, 0 },
778 { VCTLXProp, 0, 0, 0 }, 783 { VCTLXProp, 0, 0, 0 },
779 { VCTodoProp, 0, 0, PD_BEGIN }, 784 { VCTodoProp, 0, 0, PD_BEGIN },
780 { VCTranspProp, 0, 0, 0 }, 785 { VCTranspProp, 0, 0, 0 },
781 { VCUniqueStringProp, 0, 0, 0 }, 786 { VCUniqueStringProp, 0, 0, 0 },
782 { VCURLProp, 0, 0, 0 }, 787 { VCURLProp, 0, 0, 0 },
783 { VCURLValueProp, 0, 0, 0 }, 788 { VCURLValueProp, 0, 0, 0 },
784 { VCValueProp, 0, 0, 0 }, 789 { VCValueProp, 0, 0, 0 },
785 { VCVersionProp, 0, 0, 0 }, 790 { VCVersionProp, 0, 0, 0 },
786 { VCVideoProp, 0, 0, 0 }, 791 { VCVideoProp, 0, 0, 0 },
787 { VCVoiceProp, 0, 0, 0 }, 792 { VCVoiceProp, 0, 0, 0 },
788 { VCWAVEProp, 0, 0, 0 }, 793 { VCWAVEProp, 0, 0, 0 },
789 { VCWMFProp, 0, 0, 0 }, 794 { VCWMFProp, 0, 0, 0 },
790 { VCWorkProp, 0, 0, 0 }, 795 { VCWorkProp, 0, 0, 0 },
791 { VCX400Prop, 0, 0, 0 }, 796 { VCX400Prop, 0, 0, 0 },
792 { VCX509Prop, 0, 0, 0 }, 797 { VCX509Prop, 0, 0, 0 },
793 { VCXRuleProp, 0, 0, 0 }, 798 { VCXRuleProp, 0, 0, 0 },
794 { 0,0,0,0 } 799 { 0,0,0,0 }
795 }; 800 };
796 801
797 802
798static struct PreDefProp* lookupPropInfo(const char* str) 803static struct PreDefProp* lookupPropInfo(const char* str)
799{ 804{
800 /* brute force for now, could use a hash table here. */ 805 /* brute force for now, could use a hash table here. */
801 int i; 806 int i;
802 807
803 for (i = 0; propNames[i].name; i++) 808 for (i = 0; propNames[i].name; i++)
804 if (qstricmp(str, propNames[i].name) == 0) { 809 if (qstricmp(str, propNames[i].name) == 0) {
805 return &propNames[i]; 810 return &propNames[i];
806 } 811 }
807 812
808 return 0; 813 return 0;
809} 814}
810 815
811 816
812DLLEXPORT(const char*) lookupProp_(const char* str) 817DLLEXPORT(const char*) lookupProp_(const char* str)
813{ 818{
814 int i; 819 int i;
815 820
816 for (i = 0; propNames[i].name; i++) 821 for (i = 0; propNames[i].name; i++)
817 if (qstricmp(str, propNames[i].name) == 0) { 822 if (qstricmp(str, propNames[i].name) == 0) {
818 const char* s; 823 const char* s;
819 s = propNames[i].alias?propNames[i].alias:propNames[i].name; 824 s = propNames[i].alias?propNames[i].alias:propNames[i].name;
820 return lookupStr(s); 825 return lookupStr(s);
821 } 826 }
822 return lookupStr(str); 827 return lookupStr(str);
823} 828}
824 829
825 830
826DLLEXPORT(const char*) lookupProp(const char* str) 831DLLEXPORT(const char*) lookupProp(const char* str)
827{ 832{
828 int i; 833 int i;
829 834
830 for (i = 0; propNames[i].name; i++) 835 for (i = 0; propNames[i].name; i++)
831 if (qstricmp(str, propNames[i].name) == 0) { 836 if (qstricmp(str, propNames[i].name) == 0) {
832 const char *s; 837 const char *s;
833 fieldedProp = propNames[i].fields; 838 fieldedProp = propNames[i].fields;
834 s = propNames[i].alias?propNames[i].alias:propNames[i].name; 839 s = propNames[i].alias?propNames[i].alias:propNames[i].name;
835 return lookupStr(s); 840 return lookupStr(s);
836 } 841 }
837 fieldedProp = 0; 842 fieldedProp = 0;
838 return lookupStr(str); 843 return lookupStr(str);
839} 844}
840 845
841 846
842/*---------------------------------------------------------------------- 847/*----------------------------------------------------------------------
843 APIs to Output text form. 848 APIs to Output text form.
844 ----------------------------------------------------------------------*/ 849 ----------------------------------------------------------------------*/
845#define OFILE_REALLOC_SIZE 256 850#define OFILE_REALLOC_SIZE 256
846typedef struct OFile { 851typedef struct OFile {
847 FILE *fp; 852 FILE *fp;
848 char *s; 853 char *s;
849 int len; 854 int len;
850 int limit; 855 int limit;
851 int alloc:1; 856 int alloc:1;
852 int fail:1; 857 int fail:1;
853 } OFile; 858 } OFile;
854 859
855#if 0 860#if 0
856static void appendsOFile(OFile *fp, const char *s) 861static void appendsOFile(OFile *fp, const char *s)
857{ 862{
858 int slen; 863 int slen;
859 if (fp->fail) return; 864 if (fp->fail) return;
860 slen = strlen(s); 865 slen = strlen(s);
861 if (fp->fp) { 866 if (fp->fp) {
862 fwrite(s,1,slen,fp->fp); 867 fwrite(s,1,slen,fp->fp);
863 } 868 }
864 else { 869 else {
865stuff: 870stuff:
866 if (fp->len + slen < fp->limit) { 871 if (fp->len + slen < fp->limit) {
867 memcpy(fp->s+fp->len,s,slen); 872 memcpy(fp->s+fp->len,s,slen);
868 fp->len += slen; 873 fp->len += slen;
869 return; 874 return;
870 } 875 }
871 else if (fp->alloc) { 876 else if (fp->alloc) {
872 fp->limit = fp->limit + OFILE_REALLOC_SIZE; 877 fp->limit = fp->limit + OFILE_REALLOC_SIZE;
873 if (OFILE_REALLOC_SIZE <= slen) fp->limit += slen; 878 if (OFILE_REALLOC_SIZE <= slen) fp->limit += slen;
874 fp->s = (char *) realloc(fp->s,fp->limit); 879 fp->s = (char *) realloc(fp->s,fp->limit);
875 if (fp->s) goto stuff; 880 if (fp->s) goto stuff;
876 } 881 }
877 if (fp->alloc) 882 if (fp->alloc)
878 free(fp->s); 883 free(fp->s);
879 fp->s = 0; 884 fp->s = 0;
880 fp->fail = 1; 885 fp->fail = 1;
881 } 886 }
882} 887}
883 888
884static void appendcOFile(OFile *fp, char c) 889static void appendcOFile(OFile *fp, char c)
885{ 890{
886 if (fp->fail) return; 891 if (fp->fail) return;
887 if (fp->fp) { 892 if (fp->fp) {
888 fputc(c,fp->fp); 893 fputc(c,fp->fp);
889 } 894 }
890 else { 895 else {
891stuff: 896stuff:
892 if (fp->len+1 < fp->limit) { 897 if (fp->len+1 < fp->limit) {
893 fp->s[fp->len] = c; 898 fp->s[fp->len] = c;
894 fp->len++; 899 fp->len++;
895 return; 900 return;
896 } 901 }
897 else if (fp->alloc) { 902 else if (fp->alloc) {
898 fp->limit = fp->limit + OFILE_REALLOC_SIZE; 903 fp->limit = fp->limit + OFILE_REALLOC_SIZE;
899 fp->s = (char *) realloc(fp->s,fp->limit); 904 fp->s = (char *) realloc(fp->s,fp->limit);
900 if (fp->s) goto stuff; 905 if (fp->s) goto stuff;
901 } 906 }
902 if (fp->alloc) 907 if (fp->alloc)
903 free(fp->s); 908 free(fp->s);
904 fp->s = 0; 909 fp->s = 0;
905 fp->fail = 1; 910 fp->fail = 1;
906 } 911 }
907} 912}
908#else 913#else
909static void appendcOFile_(OFile *fp, char c) 914static void appendcOFile_(OFile *fp, char c)
910{ 915{
911 if (fp->fail) return; 916 if (fp->fail) return;
912 if (fp->fp) { 917 if (fp->fp) {
913 fputc(c,fp->fp); 918 fputc(c,fp->fp);
914 } 919 }
915 else { 920 else {
916stuff: 921stuff:
917 if (fp->len+1 < fp->limit) { 922 if (fp->len+1 < fp->limit) {
918 fp->s[fp->len] = c; 923 fp->s[fp->len] = c;
919 fp->len++; 924 fp->len++;
920 return; 925 return;
921 } 926 }
922 else if (fp->alloc) { 927 else if (fp->alloc) {
923 fp->limit = fp->limit + OFILE_REALLOC_SIZE; 928 fp->limit = fp->limit + OFILE_REALLOC_SIZE;
924 fp->s = (char *)realloc(fp->s,fp->limit); 929 fp->s = (char *)realloc(fp->s,fp->limit);
925 if (fp->s) goto stuff; 930 if (fp->s) goto stuff;
926 } 931 }
927 if (fp->alloc) 932 if (fp->alloc)
928 free(fp->s); 933 free(fp->s);
929 fp->s = 0; 934 fp->s = 0;
930 fp->fail = 1; 935 fp->fail = 1;
931 } 936 }
932} 937}
933 938
934static void appendcOFile(OFile *fp, char c) 939static void appendcOFile(OFile *fp, char c)
935{ 940{
936 if (c == '\n') { 941 if (c == '\n') {
937 /* write out as <CR><LF> */ 942 /* write out as <CR><LF> */
938 appendcOFile_(fp,0xd); 943 appendcOFile_(fp,0xd);
939 appendcOFile_(fp,0xa); 944 appendcOFile_(fp,0xa);
940 } 945 }
941 else 946 else
942 appendcOFile_(fp,c); 947 appendcOFile_(fp,c);
943} 948}
944 949
945static void appendsOFile(OFile *fp, const char *s) 950static void appendsOFile(OFile *fp, const char *s)
946{ 951{
947 int i, slen; 952 int i, slen;
948 slen = strlen(s); 953 slen = strlen(s);
949 for (i=0; i<slen; i++) { 954 for (i=0; i<slen; i++) {
950 appendcOFile(fp,s[i]); 955 appendcOFile(fp,s[i]);
951 } 956 }
952} 957}
953 958
954#endif 959#endif
955 960
961static void appendsOFileEncCs(OFile *fp)
962{
963 if ( vobj_enc_s ) {
964 appendsOFile(fp, ";" VCEncodingProp "=");
965 appendsOFile(fp, vobj_enc_s);
966 }
967 appendsOFile(fp, ";" VCCharSetProp "=");
968 appendsOFile(fp, vobj_cs);
969}
970
971
956static void initOFile(OFile *fp, FILE *ofp) 972static void initOFile(OFile *fp, FILE *ofp)
957{ 973{
958 fp->fp = ofp; 974 fp->fp = ofp;
959 fp->s = 0; 975 fp->s = 0;
960 fp->len = 0; 976 fp->len = 0;
961 fp->limit = 0; 977 fp->limit = 0;
962 fp->alloc = 0; 978 fp->alloc = 0;
963 fp->fail = 0; 979 fp->fail = 0;
964} 980}
965 981
966static int writeBase64(OFile *fp, unsigned char *s, long len) 982static int writeBase64(OFile *fp, unsigned char *s, long len)
967{ 983{
968 long cur = 0; 984 long cur = 0;
969 int i, numQuads = 0; 985 int i, numQuads = 0;
970 unsigned long trip; 986 unsigned long trip;
971 unsigned char b; 987 unsigned char b;
972 char quad[5]; 988 char quad[5];
973#define MAXQUADS 16 989#define MAXQUADS 16
974 990
975 quad[4] = 0; 991 quad[4] = 0;
976 992
977 while (cur < len) { 993 while (cur < len) {
978 // collect the triplet of bytes into 'trip' 994 // collect the triplet of bytes into 'trip'
979 trip = 0; 995 trip = 0;
980 for (i = 0; i < 3; i++) { 996 for (i = 0; i < 3; i++) {
981 b = (cur < len) ? *(s + cur) : 0; 997 b = (cur < len) ? *(s + cur) : 0;
982 cur++; 998 cur++;
983 trip = trip << 8 | b; 999 trip = trip << 8 | b;
984 } 1000 }
985 // fill in 'quad' with the appropriate four characters 1001 // fill in 'quad' with the appropriate four characters
986 for (i = 3; i >= 0; i--) { 1002 for (i = 3; i >= 0; i--) {
987 b = (unsigned char)(trip & 0x3F); 1003 b = (unsigned char)(trip & 0x3F);
988 trip = trip >> 6; 1004 trip = trip >> 6;
989 if ((3 - i) < (cur - len)) 1005 if ((3 - i) < (cur - len))
990 quad[i] = '='; // pad char 1006 quad[i] = '='; // pad char
991 else if (b < 26) quad[i] = (char)b + 'A'; 1007 else if (b < 26) quad[i] = (char)b + 'A';
992 else if (b < 52) quad[i] = (char)(b - 26) + 'a'; 1008 else if (b < 52) quad[i] = (char)(b - 26) + 'a';
993 else if (b < 62) quad[i] = (char)(b - 52) + '0'; 1009 else if (b < 62) quad[i] = (char)(b - 52) + '0';
994 else if (b == 62) quad[i] = '+'; 1010 else if (b == 62) quad[i] = '+';
995 else quad[i] = '/'; 1011 else quad[i] = '/';
996 } 1012 }
997 // now output 'quad' with appropriate whitespace and line ending 1013 // now output 'quad' with appropriate whitespace and line ending
998 appendsOFile(fp, (numQuads == 0 ? " " : "")); 1014 appendsOFile(fp, (numQuads == 0 ? " " : ""));
999 appendsOFile(fp, quad); 1015 appendsOFile(fp, quad);
1000 appendsOFile(fp, ((cur >= len)?"\n" :(numQuads==MAXQUADS-1?"\n" : ""))); 1016 appendsOFile(fp, ((cur >= len)?"\n" :(numQuads==MAXQUADS-1?"\n" : "")));
1001 numQuads = (numQuads + 1) % MAXQUADS; 1017 numQuads = (numQuads + 1) % MAXQUADS;
1002 } 1018 }
1003 appendcOFile(fp,'\n'); 1019 appendcOFile(fp,'\n');
1004 1020
1005 return 1; 1021 return 1;
1006} 1022}
1007 1023
1008static const char *replaceChar(unsigned char c) 1024static const char *qpReplaceChar(unsigned char c)
1009{ 1025{
1010 if (c == '\n') { 1026 if (c == '\n') {
1011 return "=0A=\n"; 1027 return "=0A=\n";
1012 } else if ( 1028 } else if (
1013 (c >= 'A' && c <= 'Z') 1029 // RFC 1521
1014 || 1030 (c >= 32 && c <= 60) // Note: " " not allowed at EOL
1015 (c >= 'a' && c <= 'z')
1016 ||
1017 (c >= '0' && c <= '9')
1018 ||
1019 (c >= '\'' && c <= ')')
1020 ||
1021 (c >= '+' && c <= '-')
1022 ||
1023 (c == '/')
1024 ||
1025 (c == '?')
1026 || 1031 ||
1027 (c == ' ')) 1032 (c >= 62 && c <= 126)
1028 { 1033 )
1034 {
1029 return 0; 1035 return 0;
1030 } 1036 }
1031 1037
1032#warning "Bug-Workaround must be fixed !"
1033 // IF THIS FUNCTION RETURNES TRUE, THE DATA IS EXPORTED
1034 // AS QUOTED PRINTABLE.
1035 // BUT THE PARSER IS UNABLE TO IMPORT THIS, THEREFORE
1036 // I DECIDED TO DISABLE IT UNTIL TROLLTECH FIXES THIS BUG
1037 // SEE ALSO includesUnprintable(VObject *o)
1038 // (se)
1039
1040 return 0;
1041
1042#if 0
1043 static char trans[4]; 1038 static char trans[4];
1044 trans[0] = '='; 1039 trans[0] = '=';
1045 trans[3] = '\0'; 1040 trans[3] = '\0';
1046 int rem = c % 16; 1041 int rem = c % 16;
1047 int div = c / 16; 1042 int div = c / 16;
1048 1043
1049 if (div < 10) 1044 if (div < 10)
1050 trans[1] = '0' + div; 1045 trans[1] = '0' + div;
1051 else 1046 else
1052 trans[1] = 'A' + (div - 10); 1047 trans[1] = 'A' + (div - 10);
1053 1048
1054 if (rem < 10) 1049 if (rem < 10)
1055 trans[2] = '0' + rem; 1050 trans[2] = '0' + rem;
1056 else 1051 else
1057 trans[2] = 'A' + (rem - 10); 1052 trans[2] = 'A' + (rem - 10);
1058 1053
1059 return trans; 1054 return trans;
1060#endif
1061} 1055}
1062 1056
1063static void writeQPString(OFile *fp, const char *s) 1057static void writeEncString(OFile *fp, const char *s, bool nosemi)
1064{ 1058{
1065 /* 1059 /*
1066 only A-Z, 0-9 and 1060 only A-Z, 0-9 and
1067 "'" (ASCII code 39) 1061 "'" (ASCII code 39)
1068 "(" (ASCII code 40) 1062 "(" (ASCII code 40)
1069 ")" (ASCII code 41) 1063 ")" (ASCII code 41)
1070 "+" (ASCII code 43) 1064 "+" (ASCII code 43)
1071 "," (ASCII code 44) 1065 "," (ASCII code 44)
1072 "-" (ASCII code 45) 1066 "-" (ASCII code 45)
1073 "/" (ASCII code 47) 1067 "/" (ASCII code 47)
1074 "?" (ASCII code 63) 1068 "?" (ASCII code 63)
1075 1069
1076 should remain un-encoded. 1070 should remain un-encoded.
1077 '=' needs to be encoded as it is the escape character. 1071 '=' needs to be encoded as it is the escape character.
1078 ';' needs to be as it is a field separator. 1072 ';' needs to be as it is a field separator.
1079 1073
1080 */ 1074 */
1081 const char *p = s; 1075 const char *p = s;
1082 while (*p) { 1076 switch ( vobj_enc ) {
1083 const char *rep = replaceChar(*p); 1077 case EightBit:
1084 if (rep) 1078 while (*p) {
1085 appendsOFile(fp, rep); 1079 if ( *p == '\n' || nosemi && ( *p == '\\' || *p == ';' ) )
1086 else 1080 appendcOFile(fp, '\\');
1087 appendcOFile(fp, *p); 1081 appendcOFile(fp, *p);
1088 p++; 1082 p++;
1083 }
1084 break;
1085 case QuotedPrintable:
1086 while (*p) {
1087 const char *rep = qpReplaceChar(*p);
1088 if (rep)
1089 appendsOFile(fp, rep);
1090 else if ( *p == ';' && nosemi )
1091 appendsOFile(fp, "=3B");
1092 else if ( *p == ' ' ) {
1093 if ( !p[1] || p[1] == '\n' ) // RFC 1521
1094 appendsOFile(fp, "=20");
1095 else
1096 appendcOFile(fp, *p);
1097 } else
1098 appendcOFile(fp, *p);
1099 p++;
1100 }
1101 break;
1102 case Base64:
1103 writeBase64(fp, (unsigned char*)p, strlen(p));
1104 break;
1089 } 1105 }
1090} 1106}
1091 1107
1092static bool includesUnprintable(VObject *o) 1108static bool includesUnprintable(VObject *o)
1093{ 1109{
1094
1095#if 0
1096
1097 // IF THIS FUNCTION RETURNES TRUE, THE DATA IS EXPORTED
1098 // AS QUOTED PRINTABLE.
1099 // BUT THE PARSER IS UNABLE TO IMPORT THIS, THEREFORE
1100 // I DECIDED TO DISABLE IT UNTIL TROLLTECH FIXES THIS BUG
1101 // SEE ALSO *replaceChar(unsigned char c)
1102 // (se)
1103
1104 if (o) { 1110 if (o) {
1105 if (VALUE_TYPE(o) == VCVT_STRINGZ) { 1111 if (VALUE_TYPE(o) == VCVT_STRINGZ) {
1106 const char *p = STRINGZ_VALUE_OF(o); 1112 const char *p = STRINGZ_VALUE_OF(o);
1107 if (p) { 1113 if (p) {
1108 while (*p) { 1114 while (*p) {
1109 if (replaceChar(*p)) 1115 if (*p==' ' && (!p[1] || p[1]=='\n') // RFC 1521: spaces at ends need quoting
1116 || qpReplaceChar(*p) )
1110 return TRUE; 1117 return TRUE;
1111 p++; 1118 p++;
1112 } 1119 }
1113 } 1120 }
1114 } 1121 }
1115 } 1122 }
1116
1117#endif
1118#warning "Bug-Workaround must be fixed !"
1119
1120 return FALSE; 1123 return FALSE;
1121} 1124}
1122 1125
1123static void writeVObject_(OFile *fp, VObject *o); 1126static void writeVObject_(OFile *fp, VObject *o);
1124 1127
1125static void writeValue(OFile *fp, VObject *o, unsigned long size) 1128static void writeValue(OFile *fp, VObject *o, unsigned long size, bool nosemi)
1126{ 1129{
1127 if (o == 0) return; 1130 if (o == 0) return;
1128 switch (VALUE_TYPE(o)) { 1131 switch (VALUE_TYPE(o)) {
1129 case VCVT_STRINGZ: { 1132 case VCVT_STRINGZ: {
1130 writeQPString(fp, STRINGZ_VALUE_OF(o)); 1133 writeEncString(fp, STRINGZ_VALUE_OF(o), nosemi);
1131 break; 1134 break;
1132 } 1135 }
1133 case VCVT_UINT: { 1136 case VCVT_UINT: {
1134 char buf[16]; 1137 char buf[16];
1135 sprintf(buf,"%u", INTEGER_VALUE_OF(o)); 1138 sprintf(buf,"%u", INTEGER_VALUE_OF(o));
1136 appendsOFile(fp,buf); 1139 appendsOFile(fp,buf);
1137 break; 1140 break;
1138 } 1141 }
1139 case VCVT_ULONG: { 1142 case VCVT_ULONG: {
1140 char buf[16]; 1143 char buf[16];
1141 sprintf(buf,"%lu", LONG_VALUE_OF(o)); 1144 sprintf(buf,"%lu", LONG_VALUE_OF(o));
1142 appendsOFile(fp,buf); 1145 appendsOFile(fp,buf);
1143 break; 1146 break;
1144 } 1147 }
1145 case VCVT_RAW: { 1148 case VCVT_RAW: {
1146 appendcOFile(fp,'\n'); 1149 appendcOFile(fp,'\n');
1147 writeBase64(fp,(unsigned char*)(ANY_VALUE_OF(o)),size); 1150 writeBase64(fp,(unsigned char*)(ANY_VALUE_OF(o)),size);
1148 break; 1151 break;
1149 } 1152 }
1150 case VCVT_VOBJECT: 1153 case VCVT_VOBJECT:
1151 appendcOFile(fp,'\n'); 1154 appendcOFile(fp,'\n');
1152 writeVObject_(fp,VOBJECT_VALUE_OF(o)); 1155 writeVObject_(fp,VOBJECT_VALUE_OF(o));
1153 break; 1156 break;
1154 } 1157 }
1155} 1158}
1156 1159
1157static void writeAttrValue(OFile *fp, VObject *o) 1160static void writeAttrValue(OFile *fp, VObject *o)
1158{ 1161{
1159 if (NAME_OF(o)) { 1162 if (NAME_OF(o)) {
1160 struct PreDefProp *pi; 1163 struct PreDefProp *pi;
1161 pi = lookupPropInfo(NAME_OF(o)); 1164 pi = lookupPropInfo(NAME_OF(o));
1162 if (pi && ((pi->flags & PD_INTERNAL) != 0)) return; 1165 if (pi && ((pi->flags & PD_INTERNAL) != 0)) return;
1163 if ( includesUnprintable(o) ) { 1166 if ( includesUnprintable(o) )
1164 appendsOFile(fp, ";" VCEncodingProp "=" VCQuotedPrintableProp); 1167 appendsOFileEncCs(fp);
1165 appendsOFile(fp, ";" VCCharSetProp "=" "UTF-8");
1166 }
1167 appendcOFile(fp,';'); 1168 appendcOFile(fp,';');
1168 appendsOFile(fp,NAME_OF(o)); 1169 appendsOFile(fp,NAME_OF(o));
1169 } 1170 } else {
1170 else
1171 appendcOFile(fp,';'); 1171 appendcOFile(fp,';');
1172 }
1172 if (VALUE_TYPE(o)) { 1173 if (VALUE_TYPE(o)) {
1173 appendcOFile(fp,'='); 1174 appendcOFile(fp,'=');
1174 writeValue(fp,o,0); 1175 writeValue(fp,o,0,TRUE);
1175 } 1176 }
1176} 1177}
1177 1178
1178static void writeGroup(OFile *fp, VObject *o) 1179static void writeGroup(OFile *fp, VObject *o)
1179{ 1180{
1180 char buf1[256]; 1181 char buf1[256];
1181 char buf2[256]; 1182 char buf2[256];
1182 strcpy(buf1,NAME_OF(o)); 1183 strcpy(buf1,NAME_OF(o));
1183 while ((o=isAPropertyOf(o,VCGroupingProp)) != 0) { 1184 while ((o=isAPropertyOf(o,VCGroupingProp)) != 0) {
1184 strcpy(buf2,STRINGZ_VALUE_OF(o)); 1185 strcpy(buf2,STRINGZ_VALUE_OF(o));
1185 strcat(buf2,"."); 1186 strcat(buf2,".");
1186 strcat(buf2,buf1); 1187 strcat(buf2,buf1);
1187 strcpy(buf1,buf2); 1188 strcpy(buf1,buf2);
1188 } 1189 }
1189 appendsOFile(fp,buf1); 1190 appendsOFile(fp,buf1);
1190} 1191}
1191 1192
1192static int inList(const char **list, const char *s) 1193static int inList(const char **list, const char *s)
1193{ 1194{
1194 if (list == 0) return 0; 1195 if (list == 0) return 0;
1195 while (*list) { 1196 while (*list) {
1196 if (qstricmp(*list,s) == 0) return 1; 1197 if (qstricmp(*list,s) == 0) return 1;
1197 list++; 1198 list++;
1198 } 1199 }
1199 return 0; 1200 return 0;
1200} 1201}
1201 1202
1202static void writeProp(OFile *fp, VObject *o) 1203static void writeProp(OFile *fp, VObject *o)
1203{ 1204{
1204 if (NAME_OF(o)) { 1205 if (NAME_OF(o)) {
1205 struct PreDefProp *pi; 1206 struct PreDefProp *pi;
1206 VObjectIterator t; 1207 VObjectIterator t;
1207 const char **fields_ = 0; 1208 const char **fields_ = 0;
1208 pi = lookupPropInfo(NAME_OF(o)); 1209 pi = lookupPropInfo(NAME_OF(o));
1209 if (pi && ((pi->flags & PD_BEGIN) != 0)) { 1210 if (pi && ((pi->flags & PD_BEGIN) != 0)) {
1210 writeVObject_(fp,o); 1211 writeVObject_(fp,o);
1211 return; 1212 return;
1212 } 1213 }
1213 if (isAPropertyOf(o,VCGroupingProp)) 1214 if (isAPropertyOf(o,VCGroupingProp))
1214 writeGroup(fp,o); 1215 writeGroup(fp,o);
1215 else 1216 else
1216 appendsOFile(fp,NAME_OF(o)); 1217 appendsOFile(fp,NAME_OF(o));
1217 if (pi) fields_ = pi->fields; 1218 if (pi) fields_ = pi->fields;
1218 initPropIterator(&t,o); 1219 initPropIterator(&t,o);
1219 while (moreIteration(&t)) { 1220 while (moreIteration(&t)) {
1220 const char *s; 1221 const char *s;
1221 VObject *eachProp = nextVObject(&t); 1222 VObject *eachProp = nextVObject(&t);
1222 s = NAME_OF(eachProp); 1223 s = NAME_OF(eachProp);
1223 if (qstricmp(VCGroupingProp,s) && !inList(fields_,s)) 1224 if (qstricmp(VCGroupingProp,s) && !inList(fields_,s))
1224 writeAttrValue(fp,eachProp); 1225 writeAttrValue(fp,eachProp);
1225 } 1226 }
1226 if (fields_) { 1227 if (fields_) {
1227 int i = 0, n = 0; 1228 int i = 0, n = 0;
1228 const char** fields = fields_; 1229 const char** fields = fields_;
1229 /* output prop as fields */ 1230 /* output prop as fields */
1230 bool printable = TRUE; 1231 bool printable = TRUE;
1231 while (*fields && printable) { 1232 while (*fields && printable) {
1232 VObject *t = isAPropertyOf(o,*fields); 1233 VObject *t = isAPropertyOf(o,*fields);
1233 if (includesUnprintable(t)) 1234 if (includesUnprintable(t))
1234 printable = FALSE; 1235 printable = FALSE;
1235 fields++; 1236 fields++;
1236 } 1237 }
1237 fields = fields_; 1238 fields = fields_;
1238 if (!printable) { 1239 if (!printable)
1239 appendsOFile(fp, ";" VCEncodingProp "=" VCQuotedPrintableProp); 1240 appendsOFileEncCs(fp);
1240 appendsOFile(fp, ";" VCCharSetProp "=" "UTF-8");
1241 }
1242 appendcOFile(fp,':'); 1241 appendcOFile(fp,':');
1243 while (*fields) { 1242 while (*fields) {
1244 VObject *t = isAPropertyOf(o,*fields); 1243 VObject *t = isAPropertyOf(o,*fields);
1245 i++; 1244 i++;
1246 if (t) n = i; 1245 if (t) n = i;
1247 fields++; 1246 fields++;
1248 } 1247 }
1249 fields = fields_; 1248 fields = fields_;
1250 for (i=0;i<n;i++) { 1249 for (i=0;i<n;i++) {
1251 writeValue(fp,isAPropertyOf(o,*fields),0); 1250 writeValue(fp,isAPropertyOf(o,*fields),0,TRUE);
1252 fields++; 1251 fields++;
1253 if (i<(n-1)) appendcOFile(fp,';'); 1252 if (i<(n-1)) appendcOFile(fp,';');
1254 } 1253 }
1255 } 1254 }
1256 } 1255 }
1257 1256
1258 1257
1259 if (VALUE_TYPE(o)) { 1258 if (VALUE_TYPE(o)) {
1260 if ( includesUnprintable(o) ) { 1259 if ( includesUnprintable(o) )
1261 appendsOFile(fp, ";" VCEncodingProp "=" VCQuotedPrintableProp); 1260 appendsOFileEncCs(fp);
1262 appendsOFile(fp, ";" VCCharSetProp "=" "UTF-8");
1263 }
1264 unsigned long size = 0; 1261 unsigned long size = 0;
1265 VObject *p = isAPropertyOf(o,VCDataSizeProp); 1262 VObject *p = isAPropertyOf(o,VCDataSizeProp);
1266 if (p) size = LONG_VALUE_OF(p); 1263 if (p) size = LONG_VALUE_OF(p);
1267 appendcOFile(fp,':'); 1264 appendcOFile(fp,':');
1268 writeValue(fp,o,size); 1265 writeValue(fp,o,size,FALSE);
1269 } 1266 }
1270 1267
1271 appendcOFile(fp,'\n'); 1268 appendcOFile(fp,'\n');
1272} 1269}
1273 1270
1274static void writeVObject_(OFile *fp, VObject *o) 1271static void writeVObject_(OFile *fp, VObject *o)
1275{ 1272{
1276 if (NAME_OF(o)) { 1273 if (NAME_OF(o)) {
1277 struct PreDefProp *pi; 1274 struct PreDefProp *pi;
1278 pi = lookupPropInfo(NAME_OF(o)); 1275 pi = lookupPropInfo(NAME_OF(o));
1279 1276
1280 if (pi && ((pi->flags & PD_BEGIN) != 0)) { 1277 if (pi && ((pi->flags & PD_BEGIN) != 0)) {
1281 VObjectIterator t; 1278 VObjectIterator t;
1282 const char *begin = NAME_OF(o); 1279 const char *begin = NAME_OF(o);
1283 appendsOFile(fp,"BEGIN:"); 1280 appendsOFile(fp,"BEGIN:");
1284 appendsOFile(fp,begin); 1281 appendsOFile(fp,begin);
1285 appendcOFile(fp,'\n'); 1282 appendcOFile(fp,'\n');
1286 initPropIterator(&t,o); 1283 initPropIterator(&t,o);
1287 while (moreIteration(&t)) { 1284 while (moreIteration(&t)) {
1288 VObject *eachProp = nextVObject(&t); 1285 VObject *eachProp = nextVObject(&t);
1289 writeProp(fp, eachProp); 1286 writeProp(fp, eachProp);
1290 } 1287 }
1291 appendsOFile(fp,"END:"); 1288 appendsOFile(fp,"END:");
1292 appendsOFile(fp,begin); 1289 appendsOFile(fp,begin);
1293 appendsOFile(fp,"\n\n"); 1290 appendsOFile(fp,"\n\n");
1294 } 1291 }
1295 } 1292 }
1296} 1293}
1297 1294
1295static void initVObjectEncoding()
1296{
1297 Config pimConfig( "Beam" );
1298 pimConfig.setGroup("Send");
1299 Config devcfg(pimConfig.readEntry("DeviceConfig"),Config::File);
1300 QString enc = "QP";
1301 QString cs = "UTF-8";
1302 if ( devcfg.isValid() ) {
1303 devcfg.setGroup("Send");
1304 enc = devcfg.readEntry("Encoding","QP");
1305 cs = devcfg.readEntry("CharSet","UTF-8");
1306 }
1307 strncpy(vobj_cs,cs.latin1(),10);
1308 if ( enc == "QP" ) {
1309 vobj_enc = QuotedPrintable;
1310 vobj_enc_s = VCQuotedPrintableProp;
1311 } else if ( enc == "B64" ) {
1312 vobj_enc = Base64;
1313 vobj_enc_s = VCBase64Prop;
1314 } else {
1315 vobj_enc = EightBit;
1316 vobj_enc_s = 0;
1317 }
1318}
1319
1298void writeVObject(FILE *fp, VObject *o) 1320void writeVObject(FILE *fp, VObject *o)
1299{ 1321{
1322 initVObjectEncoding();
1323
1300 OFile ofp; 1324 OFile ofp;
1301 // ##### 1325 // #####
1302 //_setmode(_fileno(fp), _O_BINARY); 1326 //_setmode(_fileno(fp), _O_BINARY);
1303 initOFile(&ofp,fp); 1327 initOFile(&ofp,fp);
1304 writeVObject_(&ofp,o); 1328 writeVObject_(&ofp,o);
1305} 1329}
1306 1330
1307DLLEXPORT(void) writeVObjectToFile(char *fname, VObject *o) 1331DLLEXPORT(void) writeVObjectToFile(char *fname, VObject *o)
1308{ 1332{
1309 QFileDirect f( fname); 1333 QFileDirect f( fname);
1310 if ( !f.open( IO_WriteOnly ) ) { 1334 if ( !f.open( IO_WriteOnly ) ) {
1311 qWarning("Unable to open vobject write %s", fname); 1335 qWarning("Unable to open vobject write %s", fname);
1312 return; 1336 return;
1313 } 1337 }
1314 1338
1315 writeVObject( f.directHandle(),o ); 1339 writeVObject( f.directHandle(),o );
1316} 1340}
1317 1341
1318DLLEXPORT(void) writeVObjectsToFile(char *fname, VObject *list) 1342DLLEXPORT(void) writeVObjectsToFile(char *fname, VObject *list)
1319{ 1343{
1320 QFileDirect f( fname); 1344 QFileDirect f( fname);
1321 if ( !f.open( IO_WriteOnly ) ) { 1345 if ( !f.open( IO_WriteOnly ) ) {
1322 qWarning("Unable to open vobject write %s", fname); 1346 qWarning("Unable to open vobject write %s", fname);
1323 return; 1347 return;
1324 } 1348 }
1325 1349
1326 while (list) { 1350 while (list) {
1327 writeVObject(f.directHandle(),list); 1351 writeVObject(f.directHandle(),list);
1328 list = nextVObjectInList(list); 1352 list = nextVObjectInList(list);
1329 } 1353 }
1330} 1354}
1331 1355
1332#ifndef __SHARP_COMP_
1333
1334// This function is not available in the Sharp ROM for SL 5500 !
1335// Therefore I have to move it into the header file.. (se)
1336
1337DLLEXPORT(const char *) vObjectTypeInfo(VObject *o) 1356DLLEXPORT(const char *) vObjectTypeInfo(VObject *o)
1338{ 1357{
1339 const char *type = vObjectName( o ); 1358 const char *type = vObjectName( o );
1340 if ( strcmp( type, "TYPE" ) == 0 ) 1359 if ( strcmp( type, "TYPE" ) == 0 )
1341 type = vObjectStringZValue( o ); 1360 type = vObjectStringZValue( o );
1342 return type; 1361 return type;
1343} 1362}
1344#endif 1363
1345 1364
1346// end of source file vobject.c 1365// end of source file vobject.c
diff --git a/library/backend/vobject_p.h b/library/backend/vobject_p.h
index bab22bb..f969898 100644
--- a/library/backend/vobject_p.h
+++ b/library/backend/vobject_p.h
@@ -6,197 +6,201 @@ For purposes of this license notice, the term Licensors shall mean,
6collectively, Apple Computer, Inc., AT&T Corp., International 6collectively, Apple Computer, Inc., AT&T Corp., International
7Business Machines Corporation and Siemens Rolm Communications Inc. 7Business Machines Corporation and Siemens Rolm Communications Inc.
8The term Licensor shall mean any of the Licensors. 8The term Licensor shall mean any of the Licensors.
9 9
10Subject to acceptance of the following conditions, permission is hereby 10Subject to acceptance of the following conditions, permission is hereby
11granted by Licensors without the need for written agreement and without 11granted by Licensors without the need for written agreement and without
12license or royalty fees, to use, copy, modify and distribute this 12license or royalty fees, to use, copy, modify and distribute this
13software for any purpose. 13software for any purpose.
14 14
15The above copyright notice and the following four paragraphs must be 15The above copyright notice and the following four paragraphs must be
16reproduced in all copies of this software and any software including 16reproduced in all copies of this software and any software including
17this software. 17this software.
18 18
19THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS AND NO LICENSOR SHALL HAVE 19THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS AND NO LICENSOR SHALL HAVE
20ANY OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS OR 20ANY OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS OR
21MODIFICATIONS. 21MODIFICATIONS.
22 22
23IN NO EVENT SHALL ANY LICENSOR BE LIABLE TO ANY PARTY FOR DIRECT, 23IN NO EVENT SHALL ANY LICENSOR BE LIABLE TO ANY PARTY FOR DIRECT,
24INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES OR LOST PROFITS ARISING OUT 24INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES OR LOST PROFITS ARISING OUT
25OF THE USE OF THIS SOFTWARE EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 25OF THE USE OF THIS SOFTWARE EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
26DAMAGE. 26DAMAGE.
27 27
28EACH LICENSOR SPECIFICALLY DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, 28EACH LICENSOR SPECIFICALLY DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED,
29INCLUDING BUT NOT LIMITED TO ANY WARRANTY OF NONINFRINGEMENT OR THE 29INCLUDING BUT NOT LIMITED TO ANY WARRANTY OF NONINFRINGEMENT OR THE
30IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 30IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
31PURPOSE. 31PURPOSE.
32 32
33The software is provided with RESTRICTED RIGHTS. Use, duplication, or 33The software is provided with RESTRICTED RIGHTS. Use, duplication, or
34disclosure by the government are subject to restrictions set forth in 34disclosure by the government are subject to restrictions set forth in
35DFARS 252.227-7013 or 48 CFR 52.227-19, as applicable. 35DFARS 252.227-7013 or 48 CFR 52.227-19, as applicable.
36 36
37***************************************************************************/ 37***************************************************************************/
38 38
39/* 39/*
40 40
41The vCard/vCalendar C interface is implemented in the set 41The vCard/vCalendar C interface is implemented in the set
42of files as follows: 42of files as follows:
43 43
44vcc.y, yacc source, and vcc.c, the yacc output you will use 44vcc.y, yacc source, and vcc.c, the yacc output you will use
45implements the core parser 45implements the core parser
46 46
47vobject.c implements an API that insulates the caller from 47vobject.c implements an API that insulates the caller from
48the parser and changes in the vCard/vCalendar BNF 48the parser and changes in the vCard/vCalendar BNF
49 49
50port.h defines compilation environment dependent stuff 50port.h defines compilation environment dependent stuff
51 51
52vcc.h and vobject.h are header files for their .c counterparts 52vcc.h and vobject.h are header files for their .c counterparts
53 53
54vcaltmp.h and vcaltmp.c implement vCalendar "macro" functions 54vcaltmp.h and vcaltmp.c implement vCalendar "macro" functions
55which you may find useful. 55which you may find useful.
56 56
57test.c is a standalone test driver that exercises some of 57test.c is a standalone test driver that exercises some of
58the features of the APIs provided. Invoke test.exe on a 58the features of the APIs provided. Invoke test.exe on a
59VCARD/VCALENDAR input text file and you will see the pretty 59VCARD/VCALENDAR input text file and you will see the pretty
60print output of the internal representation (this pretty print 60print output of the internal representation (this pretty print
61output should give you a good idea of how the internal 61output should give you a good idea of how the internal
62representation looks like -- there is one such output in the 62representation looks like -- there is one such output in the
63following too). Also, a file with the .out suffix is generated 63following too). Also, a file with the .out suffix is generated
64to show that the internal representation can be written back 64to show that the internal representation can be written back
65in the original text format. 65in the original text format.
66 66
67For more information on this API see the readme.txt file 67For more information on this API see the readme.txt file
68which accompanied this distribution. 68which accompanied this distribution.
69 69
70 Also visit: 70 Also visit:
71 71
72 http://www.versit.com 72 http://www.versit.com
73 http://www.ralden.com 73 http://www.ralden.com
74 74
75*/ 75*/
76 76
77// No tr() anywhere in this file 77// No tr() anywhere in this file
78 78
79 79
80#ifndef __VOBJECT_H__ 80#ifndef __VOBJECT_H__
81#define __VOBJECT_H__ 1 81#define __VOBJECT_H__ 1
82 82
83#include <qstring.h> 83#include <qstring.h>
84 84
85 #define vCardClipboardFormat "+//ISBN 1-887687-00-9::versit::PDI//vCard" 85 #define vCardClipboardFormat "+//ISBN 1-887687-00-9::versit::PDI//vCard"
86 #define vCalendarClipboardFormat"+//ISBN 1-887687-00-9::versit::PDI//vCalendar" 86 #define vCalendarClipboardFormat"+//ISBN 1-887687-00-9::versit::PDI//vCalendar"
87 87
88/* The above strings vCardClipboardFormat and vCalendarClipboardFormat 88/* The above strings vCardClipboardFormat and vCalendarClipboardFormat
89are globally unique IDs which can be used to generate clipboard format 89are globally unique IDs which can be used to generate clipboard format
90ID's as per the requirements of a specific platform. For example, in 90ID's as per the requirements of a specific platform. For example, in
91Windows they are used as the parameter in a call to RegisterClipboardFormat. 91Windows they are used as the parameter in a call to RegisterClipboardFormat.
92For example: 92For example:
93 93
94 CLIPFORMAT foo = RegisterClipboardFormat(vCardClipboardFormat); 94 CLIPFORMAT foo = RegisterClipboardFormat(vCardClipboardFormat);
95 95
96*/ 96*/
97 97
98 #define vCardMimeType "text/x-vCard" 98 #define vCardMimeType "text/x-vCard"
99 #define vCalendarMimeType"text/x-vCalendar" 99 #define vCalendarMimeType"text/x-vCalendar"
100 100
101#undef DLLEXPORT 101#undef DLLEXPORT
102 //#include <qtopia/qpeglobal.h>
102#include <qglobal.h> 103#include <qglobal.h>
103#if defined(Q_WS_WIN) 104
105#if defined(QTOPIA_MAKEDLL)
104#define DLLEXPORT(t) __declspec(dllexport) t 106#define DLLEXPORT(t) __declspec(dllexport) t
107#elif defined(QTOPIA_DLL)
108#define DLLEXPORT(t) __declspec(dllimport) t
105#else 109#else
106#define DLLEXPORT(t) t 110#define DLLEXPORT(t) t
107#endif 111#endif
108 112
109#ifndef FALSE 113#ifndef FALSE
110 #define FALSE0 114 #define FALSE0
111#endif 115#endif
112#ifndef TRUE 116#ifndef TRUE
113 #define TRUE1 117 #define TRUE1
114#endif 118#endif
115 119
116#include <stdlib.h> 120#include <stdlib.h>
117#include <stdio.h> 121#include <stdio.h>
118 122
119 123
120 #define VC7bitProp "7BIT" 124 #define VC7bitProp "7BIT"
121 #define VC8bitProp "8BIT" 125 #define VC8bitProp "8BIT"
122 #define VCAAlarmProp "AALARM" 126 #define VCAAlarmProp "AALARM"
123 #define VCAdditionalNamesProp"ADDN" 127 #define VCAdditionalNamesProp"ADDN"
124 #define VCAdrProp "ADR" 128 #define VCAdrProp "ADR"
125 #define VCAgentProp "AGENT" 129 #define VCAgentProp "AGENT"
126 #define VCAIFFProp "AIFF" 130 #define VCAIFFProp "AIFF"
127 #define VCAOLProp "AOL" 131 #define VCAOLProp "AOL"
128 #define VCAppleLinkProp "APPLELINK" 132 #define VCAppleLinkProp "APPLELINK"
129 #define VCAttachProp "ATTACH" 133 #define VCAttachProp "ATTACH"
130 #define VCAttendeeProp "ATTENDEE" 134 #define VCAttendeeProp "ATTENDEE"
131 #define VCATTMailProp "ATTMAIL" 135 #define VCATTMailProp "ATTMAIL"
132 #define VCAudioContentProp "AUDIOCONTENT" 136 #define VCAudioContentProp "AUDIOCONTENT"
133 #define VCAVIProp "AVI" 137 #define VCAVIProp "AVI"
134 #define VCBase64Prop "BASE64" 138 #define VCBase64Prop "BASE64"
135 #define VCBBSProp "BBS" 139 #define VCBBSProp "BBS"
136 #define VCBirthDateProp "BDAY" 140 #define VCBirthDateProp "BDAY"
137 #define VCBMPProp "BMP" 141 #define VCBMPProp "BMP"
138 #define VCBodyProp "BODY" 142 #define VCBodyProp "BODY"
139 #define VCBusinessRoleProp "ROLE" 143 #define VCBusinessRoleProp "ROLE"
140 #define VCCalProp "VCALENDAR" 144 #define VCCalProp "VCALENDAR"
141 #define VCCaptionProp "CAP" 145 #define VCCaptionProp "CAP"
142 #define VCCardProp "VCARD" 146 #define VCCardProp "VCARD"
143 #define VCCarProp "CAR" 147 #define VCCarProp "CAR"
144 #define VCCategoriesProp "CATEGORIES" 148 #define VCCategoriesProp "CATEGORIES"
145 #define VCCellularProp "CELL" 149 #define VCCellularProp "CELL"
146 #define VCCGMProp "CGM" 150 #define VCCGMProp "CGM"
147 #define VCCharSetProp "CHARSET" 151 #define VCCharSetProp "CHARSET"
148 #define VCCIDProp "CID" 152 #define VCCIDProp "CID"
149 #define VCCISProp "CIS" 153 #define VCCISProp "CIS"
150 #define VCCityProp "L" 154 #define VCCityProp "L"
151 #define VCClassProp "CLASS" 155 #define VCClassProp "CLASS"
152 #define VCCommentProp "NOTE" 156 #define VCCommentProp "NOTE"
153 #define VCCompletedProp "COMPLETED" 157 #define VCCompletedProp "COMPLETED"
154 #define VCContentIDProp "CONTENT-ID" 158 #define VCContentIDProp "CONTENT-ID"
155 #define VCCountryNameProp "C" 159 #define VCCountryNameProp "C"
156 #define VCDAlarmProp "DALARM" 160 #define VCDAlarmProp "DALARM"
157 #define VCDataSizeProp "DATASIZE" 161 #define VCDataSizeProp "DATASIZE"
158 #define VCDayLightProp "DAYLIGHT" 162 #define VCDayLightProp "DAYLIGHT"
159 #define VCDCreatedProp "DCREATED" 163 #define VCDCreatedProp "DCREATED"
160#define VCDeliveryLabelProp "LABEL" 164#define VCDeliveryLabelProp "LABEL"
161 #define VCDescriptionProp "DESCRIPTION" 165 #define VCDescriptionProp "DESCRIPTION"
162 #define VCDIBProp "DIB" 166 #define VCDIBProp "DIB"
163 #define VCDisplayStringProp "DISPLAYSTRING" 167 #define VCDisplayStringProp "DISPLAYSTRING"
164 #define VCDomesticProp "DOM" 168 #define VCDomesticProp "DOM"
165 #define VCDTendProp "DTEND" 169 #define VCDTendProp "DTEND"
166 #define VCDTstartProp "DTSTART" 170 #define VCDTstartProp "DTSTART"
167 #define VCDueProp "DUE" 171 #define VCDueProp "DUE"
168 #define VCEmailAddressProp "EMAIL" 172 #define VCEmailAddressProp "EMAIL"
169 #define VCEncodingProp "ENCODING" 173 #define VCEncodingProp "ENCODING"
170 #define VCEndProp "END" 174 #define VCEndProp "END"
171 #define VCEventProp "VEVENT" 175 #define VCEventProp "VEVENT"
172 #define VCEWorldProp "EWORLD" 176 #define VCEWorldProp "EWORLD"
173 #define VCExNumProp "EXNUM" 177 #define VCExNumProp "EXNUM"
174 #define VCExpDateProp "EXDATE" 178 #define VCExpDateProp "EXDATE"
175 #define VCExpectProp "EXPECT" 179 #define VCExpectProp "EXPECT"
176 #define VCExtAddressProp "EXT ADD" 180 #define VCExtAddressProp "EXT ADD"
177 #define VCFamilyNameProp "F" 181 #define VCFamilyNameProp "F"
178 #define VCFaxProp "FAX" 182 #define VCFaxProp "FAX"
179 #define VCFullNameProp "FN" 183 #define VCFullNameProp "FN"
180 #define VCGeoProp "GEO" 184 #define VCGeoProp "GEO"
181 #define VCGeoLocationProp "GEO" 185 #define VCGeoLocationProp "GEO"
182 #define VCGIFProp "GIF" 186 #define VCGIFProp "GIF"
183 #define VCGivenNameProp "G" 187 #define VCGivenNameProp "G"
184 #define VCGroupingProp "Grouping" 188 #define VCGroupingProp "Grouping"
185 #define VCHomeProp "HOME" 189 #define VCHomeProp "HOME"
186 #define VCIBMMailProp "IBMMail" 190 #define VCIBMMailProp "IBMMail"
187 #define VCInlineProp "INLINE" 191 #define VCInlineProp "INLINE"
188 #define VCInternationalProp "INTL" 192 #define VCInternationalProp "INTL"
189 #define VCInternetProp "INTERNET" 193 #define VCInternetProp "INTERNET"
190 #define VCISDNProp "ISDN" 194 #define VCISDNProp "ISDN"
191 #define VCJPEGProp "JPEG" 195 #define VCJPEGProp "JPEG"
192 #define VCLanguageProp "LANG" 196 #define VCLanguageProp "LANG"
193 #define VCLastModifiedProp "LAST-MODIFIED" 197 #define VCLastModifiedProp "LAST-MODIFIED"
194 #define VCLastRevisedProp "REV" 198 #define VCLastRevisedProp "REV"
195 #define VCLocationProp "LOCATION" 199 #define VCLocationProp "LOCATION"
196 #define VCLogoProp "LOGO" 200 #define VCLogoProp "LOGO"
197 #define VCMailerProp "MAILER" 201 #define VCMailerProp "MAILER"
198 #define VCMAlarmProp "MALARM" 202 #define VCMAlarmProp "MALARM"
199 #define VCMCIMailProp "MCIMAIL" 203 #define VCMCIMailProp "MCIMAIL"
200 #define VCMessageProp "MSG" 204 #define VCMessageProp "MSG"
201 #define VCMETProp "MET" 205 #define VCMETProp "MET"
202 #define VCModemProp "MODEM" 206 #define VCModemProp "MODEM"
@@ -258,164 +262,149 @@ For example:
258 #define VCTelephoneProp "TEL" 262 #define VCTelephoneProp "TEL"
259 #define VCTIFFProp "TIFF" 263 #define VCTIFFProp "TIFF"
260 #define VCTimeZoneProp "TZ" 264 #define VCTimeZoneProp "TZ"
261 #define VCTitleProp "TITLE" 265 #define VCTitleProp "TITLE"
262 #define VCTLXProp "TLX" 266 #define VCTLXProp "TLX"
263 #define VCTodoProp "VTODO" 267 #define VCTodoProp "VTODO"
264 #define VCTranspProp "TRANSP" 268 #define VCTranspProp "TRANSP"
265 #define VCUniqueStringProp "UID" 269 #define VCUniqueStringProp "UID"
266 #define VCURLProp "URL" 270 #define VCURLProp "URL"
267 #define VCURLValueProp "URLVAL" 271 #define VCURLValueProp "URLVAL"
268 #define VCValueProp "VALUE" 272 #define VCValueProp "VALUE"
269 #define VCVersionProp "VERSION" 273 #define VCVersionProp "VERSION"
270 #define VCVideoProp "VIDEO" 274 #define VCVideoProp "VIDEO"
271 #define VCVoiceProp "VOICE" 275 #define VCVoiceProp "VOICE"
272 #define VCWAVEProp "WAVE" 276 #define VCWAVEProp "WAVE"
273 #define VCWMFProp "WMF" 277 #define VCWMFProp "WMF"
274 #define VCWorkProp "WORK" 278 #define VCWorkProp "WORK"
275 #define VCX400Prop "X400" 279 #define VCX400Prop "X400"
276 #define VCX509Prop "X509" 280 #define VCX509Prop "X509"
277 #define VCXRuleProp "XRULE" 281 #define VCXRuleProp "XRULE"
278 282
279 283
280typedef struct VObject VObject; 284typedef struct VObject VObject;
281 285
282typedef struct VObjectIterator { 286typedef struct VObjectIterator {
283 VObject* start; 287 VObject* start;
284 VObject* next; 288 VObject* next;
285 } VObjectIterator; 289 } VObjectIterator;
286 290
287extern DLLEXPORT(VObject*) newVObject(const char *id); 291extern DLLEXPORT(VObject*) newVObject(const char *id);
288extern DLLEXPORT(void) deleteVObject(VObject *p); 292extern DLLEXPORT(void) deleteVObject(VObject *p);
289extern DLLEXPORT(char*) dupStr(const char *s, unsigned int size); 293extern DLLEXPORT(char*) dupStr(const char *s, unsigned int size);
290extern DLLEXPORT(void) deleteStr(const char *p); 294extern DLLEXPORT(void) deleteStr(const char *p);
291extern DLLEXPORT(void) unUseStr(const char *s); 295extern DLLEXPORT(void) unUseStr(const char *s);
292 296
293extern DLLEXPORT(void) setVObjectName(VObject *o, const char* id); 297extern DLLEXPORT(void) setVObjectName(VObject *o, const char* id);
294extern DLLEXPORT(void) setVObjectStringZValue(VObject *o, const char *s); 298extern DLLEXPORT(void) setVObjectStringZValue(VObject *o, const char *s);
295extern DLLEXPORT(void) setVObjectStringZValue_(VObject *o, const char *s); 299extern DLLEXPORT(void) setVObjectStringZValue_(VObject *o, const char *s);
296extern DLLEXPORT(void) setVObjectIntegerValue(VObject *o, unsigned int i); 300extern DLLEXPORT(void) setVObjectIntegerValue(VObject *o, unsigned int i);
297extern DLLEXPORT(void) setVObjectLongValue(VObject *o, unsigned long l); 301extern DLLEXPORT(void) setVObjectLongValue(VObject *o, unsigned long l);
298extern DLLEXPORT(void) setVObjectAnyValue(VObject *o, void *t); 302extern DLLEXPORT(void) setVObjectAnyValue(VObject *o, void *t);
299extern DLLEXPORT(VObject*) setValueWithSize(VObject *prop, void *val, unsigned int size); 303extern DLLEXPORT(VObject*) setValueWithSize(VObject *prop, void *val, unsigned int size);
300extern DLLEXPORT(VObject*) setValueWithSize_(VObject *prop, void *val, unsigned int size); 304extern DLLEXPORT(VObject*) setValueWithSize_(VObject *prop, void *val, unsigned int size);
301 305
302extern DLLEXPORT(const char*) vObjectName(VObject *o); 306extern DLLEXPORT(const char*) vObjectName(VObject *o);
303extern DLLEXPORT(const char*) vObjectStringZValue(VObject *o); 307extern DLLEXPORT(const char*) vObjectStringZValue(VObject *o);
304extern DLLEXPORT(unsigned int) vObjectIntegerValue(VObject *o); 308extern DLLEXPORT(unsigned int) vObjectIntegerValue(VObject *o);
305extern DLLEXPORT(unsigned long) vObjectLongValue(VObject *o); 309extern DLLEXPORT(unsigned long) vObjectLongValue(VObject *o);
306extern DLLEXPORT(void*) vObjectAnyValue(VObject *o); 310extern DLLEXPORT(void*) vObjectAnyValue(VObject *o);
307extern DLLEXPORT(VObject*) vObjectVObjectValue(VObject *o); 311extern DLLEXPORT(VObject*) vObjectVObjectValue(VObject *o);
308extern DLLEXPORT(void) setVObjectVObjectValue(VObject *o, VObject *p); 312extern DLLEXPORT(void) setVObjectVObjectValue(VObject *o, VObject *p);
309 313
310extern DLLEXPORT(VObject*) addVObjectProp(VObject *o, VObject *p); 314extern DLLEXPORT(VObject*) addVObjectProp(VObject *o, VObject *p);
311extern DLLEXPORT(VObject*) addProp(VObject *o, const char *id); 315extern DLLEXPORT(VObject*) addProp(VObject *o, const char *id);
312extern DLLEXPORT(VObject*) addProp_(VObject *o, const char *id); 316extern DLLEXPORT(VObject*) addProp_(VObject *o, const char *id);
313extern DLLEXPORT(VObject*) addPropValue(VObject *o, const char *p, const char *v); 317extern DLLEXPORT(VObject*) addPropValue(VObject *o, const char *p, const char *v);
314extern DLLEXPORT(VObject*) addPropSizedValue_(VObject *o, const char *p, const char *v, unsigned int size); 318extern DLLEXPORT(VObject*) addPropSizedValue_(VObject *o, const char *p, const char *v, unsigned int size);
315extern DLLEXPORT(VObject*) addPropSizedValue(VObject *o, const char *p, const char *v, unsigned int size); 319extern DLLEXPORT(VObject*) addPropSizedValue(VObject *o, const char *p, const char *v, unsigned int size);
316extern DLLEXPORT(VObject*) addGroup(VObject *o, const char *g); 320extern DLLEXPORT(VObject*) addGroup(VObject *o, const char *g);
317extern DLLEXPORT(void) addList(VObject **o, VObject *p); 321extern DLLEXPORT(void) addList(VObject **o, VObject *p);
318 322
319extern DLLEXPORT(VObject*) isAPropertyOf(VObject *o, const char *id); 323extern DLLEXPORT(VObject*) isAPropertyOf(VObject *o, const char *id);
320 324
321extern DLLEXPORT(VObject*) nextVObjectInList(VObject *o); 325extern DLLEXPORT(VObject*) nextVObjectInList(VObject *o);
322extern DLLEXPORT(void) initPropIterator(VObjectIterator *i, VObject *o); 326extern DLLEXPORT(void) initPropIterator(VObjectIterator *i, VObject *o);
323extern DLLEXPORT(int) moreIteration(VObjectIterator *i); 327extern DLLEXPORT(int) moreIteration(VObjectIterator *i);
324extern DLLEXPORT(VObject*) nextVObject(VObjectIterator *i); 328extern DLLEXPORT(VObject*) nextVObject(VObjectIterator *i);
325 329
326extern DLLEXPORT(const char*) lookupStr(const char *s); 330extern DLLEXPORT(const char*) lookupStr(const char *s);
327extern DLLEXPORT(void) cleanStrTbl(); 331extern DLLEXPORT(void) cleanStrTbl();
328 332
329extern DLLEXPORT(void) cleanVObject(VObject *o); 333extern DLLEXPORT(void) cleanVObject(VObject *o);
330extern DLLEXPORT(void) cleanVObjects(VObject *list); 334extern DLLEXPORT(void) cleanVObjects(VObject *list);
331 335
332extern DLLEXPORT(const char*) lookupProp(const char* str); 336extern DLLEXPORT(const char*) lookupProp(const char* str);
333extern DLLEXPORT(const char*) lookupProp_(const char* str); 337extern DLLEXPORT(const char*) lookupProp_(const char* str);
334 338
335extern DLLEXPORT(void) writeVObjectToFile(char *fname, VObject *o); 339extern DLLEXPORT(void) writeVObjectToFile(char *fname, VObject *o);
336extern DLLEXPORT(void) writeVObjectsToFile(char *fname, VObject *list); 340extern DLLEXPORT(void) writeVObjectsToFile(char *fname, VObject *list);
337 341
338extern DLLEXPORT(int) vObjectValueType(VObject *o); 342extern DLLEXPORT(int) vObjectValueType(VObject *o);
339 343
340/* return type of vObjectValueType: */ 344/* return type of vObjectValueType: */
341 #define VCVT_NOVALUE0 345 #define VCVT_NOVALUE0
342 /* if the VObject has no value associated with it. */ 346 /* if the VObject has no value associated with it. */
343 #define VCVT_STRINGZ1 347 #define VCVT_STRINGZ1
344 /* if the VObject has value set by setVObjectStringZValue. */ 348 /* if the VObject has value set by setVObjectStringZValue. */
345 #define VCVT_UINT 2 349 #define VCVT_UINT 2
346 /* if the VObject has value set by setVObjectIntegerValue. */ 350 /* if the VObject has value set by setVObjectIntegerValue. */
347 #define VCVT_ULONG 3 351 #define VCVT_ULONG 3
348 /* if the VObject has value set by setVObjectLongValue. */ 352 /* if the VObject has value set by setVObjectLongValue. */
349 #define VCVT_RAW 4 353 #define VCVT_RAW 4
350 /* if the VObject has value set by setVObjectAnyValue. */ 354 /* if the VObject has value set by setVObjectAnyValue. */
351 #define VCVT_VOBJECT5 355 #define VCVT_VOBJECT5
352 /* if the VObject has value set by setVObjectVObjectValue. */ 356 /* if the VObject has value set by setVObjectVObjectValue. */
353 357
354extern const char** fieldedProp; 358extern DLLEXPORT(const char**) fieldedProp;
355 359
356/*************************************************** 360/***************************************************
357 * The methods below are implemented in vcc.c (generated from vcc.y ) 361 * The methods below are implemented in vcc.c (generated from vcc.y )
358 ***************************************************/ 362 ***************************************************/
359 363
360/* NOTE regarding printVObject and writeVObject 364/* NOTE regarding printVObject and writeVObject
361 365
362The functions below are not exported from the DLL because they 366The functions below are not exported from the DLL because they
363take a FILE* as a parameter, which cannot be passed across a DLL 367take a FILE* as a parameter, which cannot be passed across a DLL
364interface (at least that is my experience). Instead you can use 368interface (at least that is my experience). Instead you can use
365their companion functions which take file names or pointers 369their companion functions which take file names or pointers
366to memory. However, if you are linking this code into 370to memory. However, if you are linking this code into
367your build directly then you may find them a more convenient API 371your build directly then you may find them a more convenient API
368and you can go ahead and use them. If you try to use them with 372and you can go ahead and use them. If you try to use them with
369the DLL LIB you will get a link error. 373the DLL LIB you will get a link error.
370*/ 374*/
371extern void writeVObject(FILE *fp, VObject *o); 375extern DLLEXPORT(void) writeVObject(FILE *fp, VObject *o);
372 376
373 377
374 378
375typedef void (*MimeErrorHandler)(char *); 379typedef void (*MimeErrorHandler)(char *);
376 380
377extern DLLEXPORT(void) registerMimeErrorHandler(MimeErrorHandler); 381extern DLLEXPORT(void) registerMimeErrorHandler(MimeErrorHandler);
378 382
379extern DLLEXPORT(VObject*) Parse_MIME(const char *input, unsigned long len); 383extern DLLEXPORT(VObject*) Parse_MIME(const char *input, unsigned long len);
380extern DLLEXPORT(VObject*) Parse_MIME_FromFileName(char* fname); 384extern DLLEXPORT(VObject*) Parse_MIME_FromFileName(char* fname);
381 385
382 386
383/* NOTE regarding Parse_MIME_FromFile 387/* NOTE regarding Parse_MIME_FromFile
384The function above, Parse_MIME_FromFile, comes in two flavors, 388The function above, Parse_MIME_FromFile, comes in two flavors,
385neither of which is exported from the DLL. Each version takes 389neither of which is exported from the DLL. Each version takes
386a CFile or FILE* as a parameter, neither of which can be 390a CFile or FILE* as a parameter, neither of which can be
387passed across a DLL interface (at least that is my experience). 391passed across a DLL interface (at least that is my experience).
388If you are linking this code into your build directly then 392If you are linking this code into your build directly then
389you may find them a more convenient API that the other flavors 393you may find them a more convenient API that the other flavors
390that take a file name. If you use them with the DLL LIB you 394that take a file name. If you use them with the DLL LIB you
391will get a link error. 395will get a link error.
392*/ 396*/
393 397
394 398
395#if INCLUDEMFC 399#if INCLUDEMFC
396extern VObject* Parse_MIME_FromFile(CFile *file); 400extern DLLEXPORT(VObject*) Parse_MIME_FromFile(CFile *file);
397#else 401#else
398extern VObject* Parse_MIME_FromFile(FILE *file); 402extern DLLEXPORT(VObject*) Parse_MIME_FromFile(FILE *file);
399#endif 403#endif
400 404
401#define __SHARP_COMP_
402
403#ifndef __SHARP_COMP_
404extern DLLEXPORT(const char *) vObjectTypeInfo(VObject *o); 405extern DLLEXPORT(const char *) vObjectTypeInfo(VObject *o);
405 406
406#else
407// This function is not available in the Sharp ROM for SL 5500 !
408// Therefore I have to move it into the header file.. (se)
409
410inline const char* vObjectTypeInfo(VObject *o)
411{
412 const char *type = vObjectName( o );
413 if ( strcmp( type, "TYPE" ) == 0 )
414 type = vObjectStringZValue( o );
415 return type;
416}
417#endif
418 407
419#endif /* __VOBJECT_H__ */ 408#endif /* __VOBJECT_H__ */
420 409
421 410