--- /dev/null
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#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");
+}
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)
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 {
hash[n] = p;
p->name = name;
p->value = (value? value:xstrdup(""));
+ p->modified = 1;
}
return p;
}
}
-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
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;
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;
}
}