shithub: vcardfs

Download patch

ref: 071b196a37e0e88ee005c68f84d90753d2a98a5b
parent: b6856322e21e458c9dcc4adf475c39604704b827
author: sirjofri <sirjofri@sirjofri.de>
date: Mon Oct 21 11:30:39 EDT 2024

get rid of special version and property handling.

this should make it possible to use different vcard versions, however
it also means that the user/application is responsible for validating
the vcard data.

--- a/libvcard/vcard.c
+++ b/libvcard/vcard.c
@@ -203,7 +203,6 @@
 		}
 		cs = smprint(
 			"BEGIN:VCARD\r\n"
-			"VERSION:4.0\r\n"
 			"%s"
 			"END:VCARD\r\n",
 			ls);
--- a/libvcard/vcard.h
+++ b/libvcard/vcard.h
@@ -27,6 +27,7 @@
 	char *s;
 	int invalue;
 	int inquote;
+	int haspropname;
 };
 
 extern Vstate vcstate;
--- a/libvcard/vcard.y
+++ b/libvcard/vcard.y
@@ -92,12 +92,8 @@
 %token	<i> 	BEGIN END CRLF
 
 %token	<s> 	WORD SWORD FWORD
-%token	<s> 	SOURCE KIND FN N NICKNAME PHOTO BDAY ANNIVERSARY GENDER
-%token	<s> 	ADR TEL EMAIL IMPP LANG TZ GEO TITLE ROLE LOGO ORG MEMBER
-%token	<s> 	RELATED CATEGORIES NOTE PRODID REV SOUND UID CLIENTPIDMAP
-%token	<s> 	URL KEY FBURL CALADRURI CALURI XML
+%token	<s> 	PROPNAME
 
-%type	<s> 	iana-token x-name
 %type	<s> 	pvalue
 
 %type	<vc>	vclist vcard
@@ -143,47 +139,6 @@
 	;
 
 group: SWORD;
-name:
-	  SOURCE
-	| KIND
-	| FN
-	| N
-	| NICKNAME
-	| PHOTO
-	| BDAY
-	| ANNIVERSARY
-	| GENDER
-	| ADR
-	| TEL
-	| EMAIL
-	| IMPP
-	| LANG
-	| TZ
-	| GEO
-	| TITLE
-	| ROLE
-	| LOGO
-	| ORG
-	| MEMBER
-	| RELATED
-	| CATEGORIES
-	| NOTE
-	| PRODID
-	| REV
-	| SOUND
-	| UID
-	| CLIENTPIDMAP
-	| URL
-	| KEY
-	| FBURL
-	| CALADRURI
-	| CALURI
-	| XML
-	| iana-token
-	| x-name
-	;
-
-iana-token: SWORD;
-x-name: 'x' '-' SWORD { $$ = xname($3); };
+name: PROPNAME;
 
 value: WORD | SWORD | FWORD;
--- a/libvcard/vlex.c
+++ b/libvcard/vlex.c
@@ -16,72 +16,14 @@
 char *vcparsestr;
 Vstate vcstate;
 
-typedef struct Vcname Vcname;
-struct Vcname {
-	char *str;
-	int token;
-};
+static char beginstr[] = "begin:vcard\r\n";
+static char endstr[] = "end:vcard";
 
-static char beginstr[] = "begin:vcard\r\nversion:4.0\r\n";
-
-Vcname vcnames[] = {
-	{ "end:vcard", END },
-	/* fields */
-	{ "kind", KIND },
-	{ "fn", FN },
-	{ "n", N },
-	{ "nickname", NICKNAME },
-	{ "photo", PHOTO },
-	{ "bday", BDAY },
-	{ "anniversary", ANNIVERSARY },
-	{ "gender", GENDER },
-	{ "adr", ADR },
-	{ "tel", TEL },
-	{ "email", EMAIL },
-	{ "impp", IMPP },
-	{ "lang", LANG },
-	{ "tz", TZ },
-	{ "geo", GEO },
-	{ "title", TITLE },
-	{ "role", ROLE },
-	{ "logo", LOGO },
-	{ "org", ORG },
-	{ "member", MEMBER },
-	{ "related", RELATED },
-	{ "categories", CATEGORIES },
-	{ "note", NOTE },
-	{ "prodid", PRODID },
-	{ "rev", REV },
-	{ "sound", SOUND },
-	{ "uid", UID },
-	{ "clientpidmap", CLIENTPIDMAP },
-	{ "url", URL },
-	{ "key", KEY },
-	{ "fburl", FBURL },
-	{ "caladruri", CALADRURI },
-	{ "caluri", CALURI },
-	{ "xml", XML },
-	/* params */
-	{ "language", SWORD },
-	{ "value", SWORD },
-	{ "pref", SWORD },
-	{ "altid", SWORD },
-	{ "pid", SWORD },
-	{ "type", SWORD },
-	{ "mediatype", SWORD },
-	{ "calscale", SWORD },
-	{ "sort-as", SWORD },
-	{ "geo", SWORD },
-	{ "tz", SWORD }, /* TODO: it's a duplicate! make state-dependent */
-	{ nil, 0 }
-};
-
 static char verbchars[] = ":;\"=";
 
 int
 yylex(void)
 {
-	Vcname *nm;
 	int n;
 	char *s, *t;
 	
@@ -110,6 +52,7 @@
 		memcpy(yylval.s, vcstate.s, s - vcstate.s);
 		vcstate.s = s;
 		vcstate.invalue = 0;
+		vcstate.haspropname = 0;
 		return FWORD;
 	}
 	
@@ -149,6 +92,10 @@
 	/* newline */
 	if (cistrncmp(vcstate.s, "\r\n", 2) == 0) {
 		vcstate.s += 2;
+		/* collapse multiple crlf sequences */
+		while (cistrncmp(vcstate.s, "\r\n", 2) == 0) {
+			vcstate.s += 2;
+		}
 		return CRLF;
 	}
 	
@@ -159,16 +106,23 @@
 		return BEGIN;
 	}
 	
-	/* reserved keywords */
-	for (nm = vcnames; nm->str; nm++) {
-		n = strlen(nm->str);
-		if (cistrncmp(vcstate.s, nm->str, n) == 0) {
-			yylval.s = mallocz(n+1, 1);
-			memcpy(yylval.s, vcstate.s, n);
-			iltolower(yylval.s);
-			vcstate.s += n;
-			return nm->token;
-		}
+	/* end block */
+	n = strlen(endstr);
+	if (cistrncmp(vcstate.s, endstr, n) == 0) {
+		vcstate.s += n;
+		return END;
+	}
+	
+	if (!vcstate.haspropname) {
+		s = strchr(vcstate.s, ':');
+		t = strchr(vcstate.s, ';');
+		s = s < t ? s : t;
+		n = s - vcstate.s;
+		yylval.s = mallocz(n + 1, 1);
+		memcpy(yylval.s, vcstate.s, n);
+		vcstate.s += n;
+		vcstate.haspropname++;
+		return PROPNAME;
 	}
 	
 	/* assume SWORD string (unquoted param value) */