From: Anicka Bernathova Date: Sun, 13 Jul 2008 17:10:52 +0000 (+0200) Subject: cleanup X-Git-Url: http://mj.ucw.cz/gitweb/?a=commitdiff_plain;h=d993bdf9e2d6baeaf78a6bc19c110fc38e88631a;p=umpf.git cleanup --- diff --git a/Makefile b/Makefile index 726c9c6..d594969 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ all: brum CC=gcc -CFLAGS=-Wall -W -Wno-pointer-sign -O2 -g +CFLAGS=-Wall -W -Wno-pointer-sign -g LDLIBS=-lpcre brum: brum.c cond.tab.o int.o lex.o ham.o diff --git a/brum.h b/brum.h index 4346527..2a5f939 100644 --- a/brum.h +++ b/brum.h @@ -78,6 +78,7 @@ FILE* conf; struct variable { char* name; char* value; + int modified; struct variable* next; }; @@ -87,6 +88,17 @@ struct hlist { struct hlist* next; }; +struct email { + struct hlist* headers; +}; + +struct action { + char* l; + char* r; + char* s; + struct email e; +}; + struct variable** var_hash; void print_tree(struct tree* t, int ind); @@ -99,3 +111,4 @@ void save_current_headers(struct variable** hash); struct hlist* current_headers; struct hlist* make_hlist(); void print_headers(); +void do_action(struct action* a); diff --git a/ham.c b/ham.c new file mode 100644 index 0000000..40444e1 --- /dev/null +++ b/ham.c @@ -0,0 +1,115 @@ +#include +#include +#include + +#include "brum.h" + +#define BUFSIZE 1024 + +int curbufsize; + +static char* +buf_double(char* buf, int size) +{ + buf = realloc(buf, 2*size); + + if (!buf) + die("Low memory"); + + return buf; + +} + +static struct hlist* +new_header(char* buf, struct hlist* end) +{ + char* p; + struct hlist* new; + + new = xmalloc(sizeof(struct hlist)); + + if (end) + end->next = new; + + p = strchr(buf, ':'); + + if (!p) + new->value = xstrdup(""); + else { + *p = 0; + new->value = xstrdup(p+1); + } + new->name = xstrdup(buf); + new->next = NULL; + + return new; +} + +struct hlist* +make_hlist(void) +{ + struct hlist* start = NULL, *end = NULL; + char* buf; + int i = 0; /* current position */ + int c, last = 0; + + buf = xmalloc(BUFSIZE); + curbufsize = BUFSIZE; + + while ((c = getchar()) != EOF){ + if (c == '\r') + continue; + + if (i >= curbufsize-2){ + buf = buf_double(buf, curbufsize); + curbufsize *= 2; + } + + buf[i++] = c; + if (c == '\n'){ + if (last == '\n') + break; + if ((c = getchar())!=' ' && c!='\t'){ + if (c != EOF) + ungetc(c, stdin); + buf[i] = 0; + end = new_header(buf, end); + if (!start) + start = end; + i = 0; + } else + buf[i++] = c; + } + last = c; + } + free(buf); + return start; +} + +void +print_headers(struct hlist* h) +{ + struct hlist* p = h; + + while (p){ + printf("%s:%s",p->name,p->value); + p = p->next; + } +} + +void +do_action(struct action* a) +{ + puts("--do action--"); + if (a->l) + puts(a->l); + printf("->"); + if (a->r) + puts(a->r); + putchar(' '); + if (a->s) + puts(a->s); + puts("with email\n"); + print_headers(a->e.headers); + puts("\n--Muhehehechlemst!--\n"); +} diff --git a/int.c b/int.c index 6e9a814..b83b435 100644 --- a/int.c +++ b/int.c @@ -28,21 +28,13 @@ get_bucket_number(char* name) unsigned char* p = name; while (*p != '\0'){ - n = n * MAGIC + *p++; + n = n * MAGIC + toupper(*p++); } n %= HASHSIZE; return n; } -void -cap(char* s) -{ - char* p; - for(p = s; *p; p++) - *p = toupper(*p); -} - /* value NULL for finding without modyfiing */ static struct variable* find_var(char* name, char* value, struct variable** hash) @@ -50,19 +42,22 @@ find_var(char* name, char* value, struct variable** hash) int n; struct variable *p; - name = xstrdup(name); - if (isupper(*name)) - cap(name); - n = get_bucket_number(name); p = hash[n]; - while(p && strcmp(p->name,name)) - p = p->next; + + if (isupper(*name)){ + while(p && strcasecmp(p->name,name)) + p = p->next; + } else { + while(p && strcmp(p->name,name)) + p = p->next; + } if (p && value){ free(p->value); p->value = value; + p->modified = 1; } else if (p && !value) return p; else { @@ -71,6 +66,7 @@ find_var(char* name, char* value, struct variable** hash) hash[n] = p; p->name = name; p->value = (value? value:xstrdup("")); + p->modified = 1; } return p; @@ -239,10 +235,75 @@ interp_cond(struct tree* t, struct variable** hash) } } -void -new_action(char* l, char* r, char* s) +static void +modify_headers(struct hlist* headers, struct variable** hash) +{ + struct hlist* p; + struct hlist* last = NULL; + struct variable* pv; + int i; + + for(p = headers; p; p = p->next){ + pv = find_var(p->name,NULL,hash); + if (pv->modified){ + pv->modified = 0; + free(pv->value); + pv->value = xstrdup(p->value); //FIXME: fold it + } + last = p; + } + + /* find new headers */ + for (i = 0; i < HASHSIZE; i++){ + for(pv = hash[i]; pv; pv = pv->next){ + if (isupper(pv->name[0]) && pv->modified){ + pv->modified = 0; + p = xmalloc(sizeof(struct hlist)); + + last->next = p; //FIXME + p->next = NULL; + p->name = xstrdup(pv->name); + p->value = xstrdup(pv->value); + } + } + } +} + +static struct hlist* +copy_headers(struct hlist* orig) +{ + struct hlist* new = NULL; + struct hlist* po, * pn = NULL; + + for (po = orig; po; po = po->next){ + if (!pn) + pn = xmalloc(sizeof(struct hlist)); + pn->next = xmalloc(sizeof(struct hlist)); + pn = pn->next; + pn->next = NULL; + pn->name = xstrdup(po->name); + pn->value = xstrdup(po->value); + if (!new) + new = pn; + } + + return new; +} + +static void +new_action(char* l, char* r, char* s, struct variable** hash) { - //TODO: modify headers according to variable values + struct action* a; + + a = xmalloc(sizeof(struct action)); + + modify_headers(current_headers, hash); + a->e.headers = copy_headers(current_headers); + a->l = l; + a->r = r; + a->s = s; + + do_action(a); } void @@ -266,7 +327,7 @@ interp(struct tree* t, struct variable** hash) interp(t->pt.tif.e, hash); break; case ST_ARROW: - new_action(t->pt.arrow.kw_left, t->pt.arrow.kw_right, interp_ass_right(t->pt.arrow.s, hash)); + new_action(t->pt.arrow.kw_left, t->pt.arrow.kw_right, interp_ass_right(t->pt.arrow.s, hash),hash); break; case ST_EMPTY: break; @@ -324,11 +385,13 @@ void save_current_headers(struct variable** hash) { struct hlist* p; + struct variable* pv; char* u; for (p = current_headers;p;p = p->next){ u = unfold(p->value); - find_var(p->name,u,hash); + pv = find_var(p->name,u,hash); + pv->modified = 0; } }