ref: e0cac8cff0fad58496578de0bf11f111f765d3a8
dir: /libvcard/vlex.c/
#include <u.h>
#include <libc.h>
#include "vcard.h"
#include "y.tab.h"
//#define DEBUG
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;
}
#ifdef DEBUG
fprint(2, "vcstate:\n"
" str: %p\n"
" s: %c\n"
" invalue: %d\n"
" inquote: %d\n"
" haspropname: %d\n",
vcstate.str, *vcstate.s, vcstate.invalue, vcstate.inquote, vcstate.haspropname);
#endif
/* 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;
#ifdef DEBUG
fprint(2, " FWORD: %s\n", yylval.s);
#endif
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;
#ifdef DEBUG
fprint(2, " FWORD: %s\n", yylval.s);
#endif
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++;
#ifdef DEBUG
fprint(2, " VERBCHAR: '%c'\n", n);
#endif
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;
}
#ifdef DEBUG
fprint(2, " CRLF\n");
#endif
return CRLF;
}
/* begin block */
n = strlen(beginstr);
if (cistrncmp(vcstate.s, beginstr, n) == 0) {
vcstate.s += n;
#ifdef DEBUG
fprint(2, " BEGIN\n");
#endif
return BEGIN;
}
/* end block */
n = strlen(endstr);
if (cistrncmp(vcstate.s, endstr, n) == 0) {
vcstate.s += n;
#ifdef DEBUG
fprint(2, " END\n");
#endif
return END;
}
/* assume SWORD string (unquoted param value or param name) */
s = strchr(vcstate.s, ':');
t = strchr(vcstate.s, ';');
if (t)
s = s < t ? s : t;
t = strchr(vcstate.s, '=');
if (t)
s = s < t ? s : t;
n = s - vcstate.s;
yylval.s = mallocz(n + 1, 1);
memcpy(yylval.s, vcstate.s, n);
vcstate.s += n;
#ifdef DEBUG
fprint(2, " SWORD: %s\n", yylval.s);
#endif
return SWORD;
}