"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "nvp.c" between
mairix-0.23.tar.gz and mairix-0.24.tar.gz

About: mairix is a program for indexing and searching email messages stored in maildir, MH or mbox folders.

nvp.c  (mairix-0.23):nvp.c  (mairix-0.24)
skipping to change at line 55 skipping to change at line 55
char *lhs; char *lhs;
char *rhs; char *rhs;
}; };
/*}}}*/ /*}}}*/
struct nvp {/*{{{*/ struct nvp {/*{{{*/
struct nvp_entry *first, *last; struct nvp_entry *first, *last;
}; };
/*}}}*/ /*}}}*/
static void append(struct nvp *nvp, struct nvp_entry *ne)/*{{{*/ static void append(struct nvp *nvp, struct nvp_entry *ne)/*{{{*/
{ {
if (!ne->rhs) {
ne->rhs = Malloc(1);
ne->rhs[0] = 0;
}
if (!ne->lhs) {
ne->lhs = Malloc(1);
ne->lhs[0] = 0;
}
ne->next = NULL; ne->next = NULL;
ne->prev = nvp->last; ne->prev = nvp->last;
if (nvp->last) nvp->last->next = ne; if (nvp->last) nvp->last->next = ne;
else nvp->first = ne; else nvp->first = ne;
nvp->last = ne; nvp->last = ne;
} }
/*}}}*/ /*}}}*/
static void append_name(struct nvp *nvp, char *name)/*{{{*/ static void append_name(struct nvp *nvp, char **name)/*{{{*/
{ {
struct nvp_entry *ne; struct nvp_entry *ne;
ne = new(struct nvp_entry); ne = new(struct nvp_entry);
ne->type = NVP_NAME; ne->type = NVP_NAME;
ne->lhs = new_string(name); ne->lhs = *name;
*name = NULL;
append(nvp, ne); append(nvp, ne);
} }
/*}}}*/ /*}}}*/
static void append_majorminor(struct nvp *nvp, char *major, char *minor)/*{{{*/ static void append_majorminor(struct nvp *nvp, char **major, char **minor)/*{{{* /
{ {
struct nvp_entry *ne; struct nvp_entry *ne;
ne = new(struct nvp_entry); ne = new(struct nvp_entry);
ne->type = NVP_MAJORMINOR; ne->type = NVP_MAJORMINOR;
ne->lhs = new_string(major); ne->lhs = *major;
ne->rhs = new_string(minor); ne->rhs = *minor;
*major = *minor = NULL;
append(nvp, ne); append(nvp, ne);
} }
/*}}}*/ /*}}}*/
static void append_namevalue(struct nvp *nvp, char *name, char *value)/*{{{*/ static void append_namevalue(struct nvp *nvp, char **name, char **value)/*{{{*/
{ {
struct nvp_entry *ne; struct nvp_entry *ne;
ne = new(struct nvp_entry); ne = new(struct nvp_entry);
ne->type = NVP_NAMEVALUE; ne->type = NVP_NAMEVALUE;
ne->lhs = new_string(name); ne->lhs = *name;
ne->rhs = new_string(value); ne->rhs = *value;
*name = *value = NULL;
append(nvp, ne); append(nvp, ne);
} }
/*}}}*/ /*}}}*/
static void combine_namevalue(struct nvp *nvp, char *name, char *value)/*{{{*/ static void combine_namevalue(struct nvp *nvp, char **name, char **value)/*{{{*/
{ {
struct nvp_entry *n; struct nvp_entry *n;
for (n=nvp->first; n; n=n->next) { for (n=nvp->first; n; n=n->next) {
if (n->type == NVP_NAMEVALUE) { if (n->type == NVP_NAMEVALUE) {
if (!strcmp(n->lhs, name)) { if (!strcmp(n->lhs, *name)) {
char *new_rhs; char *new_rhs;
new_rhs = new_array(char, strlen(n->rhs) + strlen(value) + 1); new_rhs = new_array(char, strlen(n->rhs) + strlen(*value) + 1);
strcpy(new_rhs, n->rhs); strcpy(new_rhs, n->rhs);
strcat(new_rhs, value); strcat(new_rhs, *value);
free(n->rhs); free(n->rhs);
n->rhs = new_rhs; n->rhs = new_rhs;
return; return;
} }
} }
} }
/* No match : it's the first one */ /* No match : it's the first one */
append_namevalue(nvp, name, value); append_namevalue(nvp, name, value);
} }
/*}}}*/ /*}}}*/
static int hex_to_val(int ch)/*{{{*/
{
if (isdigit(ch))
return (ch - '0');
if (ch >= 'a' && ch <= 'f')
return (10 + ch - 'a');
if (ch >= 'A' && ch <= 'F')
return (10 + ch - 'A');
return (-1);
}
/*}}}*/
static void release_nvp(struct nvp *nvp)/*{{{*/ static void release_nvp(struct nvp *nvp)/*{{{*/
{ {
struct nvp_entry *e, *ne; struct nvp_entry *e, *ne;
for (e=nvp->first; e; e=ne) { for (e=nvp->first; e; e=ne) {
ne = e->next; ne = e->next;
switch (e->type) { switch (e->type) {
case NVP_NAME: case NVP_NAME:
free(e->lhs); free(e->lhs);
break; break;
case NVP_MAJORMINOR: case NVP_MAJORMINOR:
skipping to change at line 136 skipping to change at line 158
} }
free(e); free(e);
} }
free(nvp); free(nvp);
} }
/*}}}*/ /*}}}*/
struct nvp *make_nvp(struct msg_src *src, char *s, const char *pfx)/*{{{*/ struct nvp *make_nvp(struct msg_src *src, char *s, const char *pfx)/*{{{*/
{ {
int current_state; int current_state;
unsigned int tok; unsigned int tok;
char *q; char *q, *tempsrc, *tempdst;
unsigned char qq; unsigned char qq;
char name[256]; char *name = NULL;
char minor[256]; char *minor = NULL;
char value[256]; char *value = NULL;
char *copy_start;
enum nvp_action last_action, current_action; enum nvp_action last_action, current_action;
enum nvp_copier last_copier;
struct nvp *result; struct nvp *result;
size_t pfxlen; size_t pfxlen;
char *nn, *mm, *vv;
pfxlen = strlen(pfx); pfxlen = strlen(pfx);
if (strncasecmp(pfx, s, pfxlen)) if (strncasecmp(pfx, s, pfxlen))
return NULL; return NULL;
s += pfxlen; s += pfxlen;
result = new(struct nvp); result = new(struct nvp);
result->first = result->last = NULL; result->first = result->last = NULL;
current_state = nvp_in; current_state = nvp_in;
q = s; q = s;
nn = name;
mm = minor;
vv = value;
last_action = GOT_NOTHING; last_action = GOT_NOTHING;
last_copier = COPY_NOWHERE;
do { do {
qq = *(unsigned char *) q; qq = *(unsigned char *) q;
if (qq) { if (qq) {
tok = nvp_char2tok[qq]; tok = nvp_char2tok[qq];
} else { } else {
tok = nvp_EOS; tok = nvp_EOS;
} }
current_state = nvp_next_state(current_state, tok); current_state = nvp_next_state(current_state, tok);
#ifdef VERBOSE_TEST #ifdef VERBOSE_TEST
fprintf(stderr, "Char %02x (%c) tok=%d new_current_state=%d\n", fprintf(stderr, "Char %02x (%c) tok=%d new_current_state=%d\n",
skipping to change at line 186 skipping to change at line 207
#ifdef TEST #ifdef TEST
fprintf(stderr, "'%s' could not be parsed\n", s); fprintf(stderr, "'%s' could not be parsed\n", s);
#else #else
fprintf(stderr, "Header '%s%s' in %s could not be parsed\n", fprintf(stderr, "Header '%s%s' in %s could not be parsed\n",
pfx, s, format_msg_src(src)); pfx, s, format_msg_src(src));
#endif #endif
release_nvp(result); release_nvp(result);
return NULL; return NULL;
} }
switch (nvp_copier[current_state]) { if (nvp_copier[current_state] != last_copier) {
case COPY_TO_NAME: if (last_copier != COPY_NOWHERE) {
char *newstring = Malloc(q - copy_start + 1);
memcpy(newstring, copy_start, q - copy_start);
newstring[q - copy_start] = 0;
switch (last_copier) {
case COPY_TO_NAME:
free(name);
name = newstring;
#ifdef VERBOSE_TEST #ifdef VERBOSE_TEST
fprintf(stderr, " COPY_TO_NAME\n"); fprintf(stderr, " COPY_TO_NAME \"%s\"\n", name);
#endif #endif
*nn++ = *q; break;
break; case COPY_TO_MINOR:
case COPY_TO_MINOR: free(minor);
minor = newstring;
#ifdef VERBOSE_TEST #ifdef VERBOSE_TEST
fprintf(stderr, " COPY_TO_MINOR\n"); fprintf(stderr, " COPY_TO_MINOR \"%s\"\n", minor);
#endif #endif
*mm++ = *q; break;
break; case COPY_TO_VALUE:
case COPY_TO_VALUE: free(value);
value = newstring;
#ifdef VERBOSE_TEST #ifdef VERBOSE_TEST
fprintf(stderr, " COPY_TO_VALUE\n"); fprintf(stderr, " COPY_TO_VALUE \"%s\"\n", value);
#endif #endif
*vv++ = *q; break;
break; case COPY_NOWHERE:
case COPY_NOWHERE: /* NOTREACHED */
break; break;
}
}
last_copier = nvp_copier[current_state];
copy_start = q;
} }
current_action = nvp_action[current_state]; current_action = nvp_action[current_state];
switch (current_action) { switch (current_action) {
case GOT_NAME: case GOT_NAME:
case GOT_NAME_TRAILING_SPACE: case GOT_NAME_TRAILING_SPACE:
case GOT_MAJORMINOR: case GOT_MAJORMINOR:
case GOT_NAMEVALUE: case GOT_NAMEVALUE:
case GOT_NAMEVALUE_CONT: case GOT_NAMEVALUE_CONT:
case GOT_NAMEVALUE_CSET:
case GOT_NAMEVALUE_CCONT:
#ifdef VERBOSE_TEST #ifdef VERBOSE_TEST
fprintf(stderr, " Setting last action to %d\n", current_action); fprintf(stderr, " Setting last action to %d\n", current_action);
#endif #endif
last_action = current_action; last_action = current_action;
break; break;
case GOT_TERMINATOR: case GOT_TERMINATOR:
#ifdef VERBOSE_TEST #ifdef VERBOSE_TEST
fprintf(stderr, " Hit terminator; last_action=%d\n", last_action); fprintf(stderr, " Hit terminator; last_action=%d\n", last_action);
#endif #endif
switch (last_action) { switch (last_action) {
case GOT_NAME: case GOT_NAME:
*nn = 0; append_name(result, &name);
append_name(result, name);
break; break;
case GOT_NAME_TRAILING_SPACE: case GOT_NAME_TRAILING_SPACE:
while (isspace(*--nn)) {} tempdst = name + strlen(name);
*++nn = 0; while (isspace(*--tempdst)) {}
append_name(result, name); *++tempdst = 0;
append_name(result, &name);
break; break;
case GOT_MAJORMINOR: case GOT_MAJORMINOR:
*nn = 0; append_majorminor(result, &name, &minor);
*mm = 0;
append_majorminor(result, name, minor);
break; break;
case GOT_NAMEVALUE: case GOT_NAMEVALUE:
*nn = 0; append_namevalue(result, &name, &value);
*vv = 0; break;
append_namevalue(result, name, value); case GOT_NAMEVALUE_CSET:
case GOT_NAMEVALUE_CCONT:
for(tempsrc = tempdst = value; *tempsrc; tempsrc++) {
if (*tempsrc == '%') {
int val = hex_to_val(*++tempsrc) << 4;
val |= hex_to_val(*++tempsrc);
if (val < 0) {
#ifdef TEST
fprintf(stderr, "'%s' could not be parsed (%%)\n", s);
#else
fprintf(stderr, "Header '%s%s' in %s could not be parsed\
n",
pfx, s, format_msg_src(src));
#endif
release_nvp(result);
result = NULL;
goto out;
}
*tempdst++ = val;
} else
*tempdst++ = *tempsrc;
}
*tempdst = 0;
if (current_action == GOT_NAMEVALUE_CSET)
append_namevalue(result, &name, &value);
else
combine_namevalue(result, &name, &value);
break; break;
case GOT_NAMEVALUE_CONT: case GOT_NAMEVALUE_CONT:
*nn = 0; combine_namevalue(result, &name, &value);
*vv = 0;
combine_namevalue(result, name, value);
break; break;
default: default:
break; break;
} }
nn = name;
mm = minor;
vv = value;
break; break;
case GOT_NOTHING: case GOT_NOTHING:
break; break;
} }
q++; q++;
} while (tok != nvp_EOS); } while (tok != nvp_EOS);
out:
/* Not all productions consume these values */
free(name);
free(value);
free(minor);
return result; return result;
} }
/*}}}*/ /*}}}*/
void free_nvp(struct nvp *nvp)/*{{{*/ void free_nvp(struct nvp *nvp)/*{{{*/
{ {
struct nvp_entry *ne, *nne; struct nvp_entry *ne, *nne;
for (ne = nvp->first; ne; ne=nne) { for (ne = nvp->first; ne; ne=nne) {
nne = ne->next; nne = ne->next;
switch (ne->type) { switch (ne->type) {
case NVP_NAME: case NVP_NAME:
skipping to change at line 395 skipping to change at line 454
struct nvp *n; struct nvp *n;
n = make_nvp(NULL, s, ""); n = make_nvp(NULL, s, "");
if (n) { if (n) {
nvp_dump(n, stderr); nvp_dump(n, stderr);
free_nvp(n); free_nvp(n);
} }
} }
int main (int argc, char **argv) { int main (int argc, char **argv) {
struct nvp *n; struct nvp *n;
if (argc > 1) {
while (*++argv)
do_test(*argv);
return 0;
}
#if 0 #if 0
do_test("attachment; filename=\"foo.c\"; prot=ro"); do_test("attachment; filename=\"foo.c\"; prot=ro");
do_test("attachment; filename= \"foo bar.c\" ;prot=ro"); do_test("attachment; filename= \"foo bar.c\" ;prot=ro");
do_test("attachment ; filename= \"foo bar.c\" ;prot= ro"); do_test("attachment ; filename= \"foo bar.c\" ;prot= ro");
do_test("attachment ; filename= \"foo bar.c\" ;prot= ro"); do_test("attachment ; filename= \"foo bar.c\" ;prot= ro");
do_test("attachment ; filename= \"foo ; bar.c\" ;prot= ro"); do_test("attachment ; filename= \"foo ; bar.c\" ;prot= ro");
do_test("attachment ; x*0=\"hi \"; x*1=\"there\""); do_test("attachment ; x*0=\"hi \"; x*1=\"there\"");
#endif #endif
do_test("attachment; filename*=utf-8''Section%204-1%20%E2%80%93%20Response%20M
do_test("application/vnd.ms-excel; name=\"thequiz.xls\""); atrix%20PartIIA%2Edoc");
#if 0 #if 0
do_test("application/vnd.ms-excel; name=\"thequiz.xls\"");
do_test("inline; filename*0=\"aaaa bbbb cccc dddd eeee ffff gggg hhhh iiii jjj j\t kkkkllll\""); do_test("inline; filename*0=\"aaaa bbbb cccc dddd eeee ffff gggg hhhh iiii jjj j\t kkkkllll\"");
do_test(" text/plain ; name= \"foo bar.c\" ;prot= ro/rw; read/write; read= foo bar"); do_test(" text/plain ; name= \"foo bar.c\" ;prot= ro/rw; read/write; read= foo bar");
#endif #endif
return 0; return 0;
} }
#endif #endif
 End of changes. 36 change blocks. 
54 lines changed or deleted 122 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)