shithub: vcardfs

ref: 071b196a37e0e88ee005c68f84d90753d2a98a5b
dir: /libvcard/vlex.c/

View raw version
#include <u.h>
#include <libc.h>
#include "vcard.h"
#include "y.tab.h"

static void
iltolower(char *s)
{
	while (*s) {
		if (*s >= 'A' && *s <= 'Z')
			*s = *s - 'A' + 'a';
		s++;
	}
}

char *vcparsestr;
Vstate vcstate;

static char beginstr[] = "begin:vcard\r\n";
static char endstr[] = "end:vcard";

static char verbchars[] = ":;\"=";

int
yylex(void)
{
	int n;
	char *s, *t;
	
	if (!vcstate.s) {
		vcstate.s = vcstate.str;
	}
	
	/*
	fprint(2, "vcstate:\n"
		"  str: %p\n"
		"  s: %c\n"
		"  invalue: %d\n"
		"  inquote: %d\n",
		vcstate.str, *vcstate.s, vcstate.invalue, vcstate.inquote);
	*/
	
	/* value string */
	if (vcstate.invalue) {
		s = strstr(vcstate.s, "\r\n");
		if (!s) {
			yylval.s = strdup(vcstate.s);
			vcstate.s = strchr(vcstate.s, 0);
			return FWORD;
		}
		yylval.s = mallocz(s - vcstate.s + 1, 1);
		memcpy(yylval.s, vcstate.s, s - vcstate.s);
		vcstate.s = s;
		vcstate.invalue = 0;
		vcstate.haspropname = 0;
		return FWORD;
	}
	
	/* quoted string */
	if (vcstate.inquote == 1) {
		s = strchr(vcstate.s, '"');
		if (!s) {
			fprint(2, "parse error: quotes not closing!\n");
			return -1;
		}
		yylval.s = mallocz(s - vcstate.s + 1, 1);
		memcpy(yylval.s, vcstate.s, s - vcstate.s);
		vcstate.s = s;
		vcstate.inquote = 2;
		return FWORD;
	}
	
	/* verbatim characters */
	if (strchr(verbchars, *vcstate.s)) {
		switch (*vcstate.s) {
		case ':':
			vcstate.invalue++;
			break;
		case '"':
			if (vcstate.inquote == 2) {
				vcstate.inquote = 0;
			} else {
				vcstate.inquote++;
			}
			break;
		}
		n = *vcstate.s;
		vcstate.s++;
		return n;
	}
	
	/* 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;
	}
	
	/* begin block */
	n = strlen(beginstr);
	if (cistrncmp(vcstate.s, beginstr, n) == 0) {
		vcstate.s += n;
		return BEGIN;
	}
	
	/* 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) */
	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;
	return SWORD;
}