CFLAGS=-Wall -W -Wno-pointer-sign -g
LDLIBS=-lpcre
-brum: brum.c cond.tab.o int.o lex.o ham.o
+brum: brum.c cond.tab.o int.o lex.o ham.o lists.o
gcc -o $@ $^ $(LDLIBS)
cond.tab.o: cond.tab.c lex.o
ham.o: ham.c
+lists.o: lists.c
+
cond.tab.c: cond.y
bison -dvt cond.y
+#include "lists.h"
+
/* cond.h */
int yylex (void);
void yyerror (char const *);
};
struct hlist {
+ struct node car;
char* name;
char* value;
- struct hlist* next;
};
struct email {
- struct hlist* headers;
+ struct list* headers;
};
struct action {
void save_current_headers(struct variable** hash);
/* ham.c */
-struct hlist* current_headers;
-struct hlist* make_hlist();
-void print_headers();
+struct list* current_headers;
+struct list* make_hlist(void);
+void print_headers(struct list* l);
void do_action(struct action* a);
int curbufsize;
-static char*
+static char* //TODO: rewrite
buf_double(char* buf, int size)
{
buf = realloc(buf, 2*size);
}
-static struct hlist*
-new_header(char* buf, struct hlist* end)
+static void
+new_header(char* buf, struct list* h)
{
char* p;
struct hlist* new;
new = xmalloc(sizeof(struct hlist));
- if (end)
- end->next = new;
-
p = strchr(buf, ':');
-
if (!p)
new->value = xstrdup("");
else {
new->value = xstrdup(p+1);
}
new->name = xstrdup(buf);
- new->next = NULL;
- return new;
+ list_add_last(h, &new->car);
}
-struct hlist*
+struct list*
make_hlist(void)
{
- struct hlist* start = NULL, *end = NULL;
+ struct list* l = xmalloc(sizeof(struct list));
char* buf;
int i = 0; /* current position */
int c, last = 0;
+ list_init(l);
buf = xmalloc(BUFSIZE);
curbufsize = BUFSIZE;
if (c != EOF)
ungetc(c, stdin);
buf[i] = 0;
- end = new_header(buf, end);
- if (!start)
- start = end;
+ new_header(buf, l);
i = 0;
} else
buf[i++] = c;
last = c;
}
free(buf);
- return start;
+ return l;
}
void
-print_headers(struct hlist* h)
+print_headers(struct list* l)
{
- struct hlist* p = h;
+ struct hlist* p;
- while (p){
+ LIST_FOREACH(p,l)
printf("%s:%s",p->name,p->value);
- p = p->next;
- }
}
void
}
static void
-modify_headers(struct hlist* headers, struct variable** hash)
+modify_headers(struct list* headers, struct variable** hash)
{
struct hlist* p;
- struct hlist* last = NULL;
struct variable* pv;
int i;
- for(p = headers; p; p = p->next){
+ LIST_FOREACH(p, headers){
pv = find_var(p->name,NULL,hash);
if (pv->modified){
pv->modified = 0;
- free(pv->value);
- pv->value = xstrdup(p->value); //FIXME: fold it
+ free(p->value);
+ p->value = xstrdup(pv->value); //FIXME: fold it
}
- last = p;
}
/* find new headers */
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 = xmalloc(sizeof(struct hlist));
p->name = xstrdup(pv->name);
p->value = xstrdup(pv->value);
+
+ list_add_last(headers,&p->car);
}
}
}
}
-static struct hlist*
-copy_headers(struct hlist* orig)
+static struct list*
+copy_headers(struct list* 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;
+ struct list* new = xmalloc(sizeof(struct list));
+ struct hlist* po, *pn;
+
+ list_init(new);
+
+ LIST_FOREACH(po, orig){
+ pn = xmalloc(sizeof(struct hlist));
pn->name = xstrdup(po->name);
pn->value = xstrdup(po->value);
- if (!new)
- new = pn;
+
+ list_add_last(new, &pn->car);
}
return new;
struct variable* pv;
char* u;
- for (p = current_headers;p;p = p->next){
+ LIST_FOREACH(p, current_headers){
u = unfold(p->value);
pv = find_var(p->name,u,hash);
pv->modified = 0;
--- /dev/null
+#include <stdio.h>
+#include <stdlib.h>
+#include "lists.h"
+
+void
+list_init(struct list* l)
+{
+ l->head.next=&l->head;
+ l->head.prev=&l->head;
+}
+
+int
+list_is_empty(struct list* l)
+{
+ return (&l->head==l->head.next);
+}
+
+/* return first element of the list or NULL if empty */
+void*
+list_first(struct list* l)
+{
+ return (&l->head!=l->head.next?l->head.next:NULL);
+}
+
+void*
+list_last(struct list* l)
+{
+ return (&l->head!=l->head.prev?l->head.prev:NULL);
+}
+
+void*
+list_prev(struct list* l, struct node* n)
+{
+ return (n->prev!=&l->head?n->prev:NULL);
+}
+
+void*
+list_next(struct list* l, struct node* n)
+{
+ return (n->next!=&l->head?n->next:NULL);
+}
+
+void
+list_add_first(struct list* l, struct node* new)
+{
+ new->prev=&l->head;
+ new->next=l->head.next;
+ l->head.next->prev=new;
+ l->head.next=new;
+}
+
+void
+list_add_last(struct list* l, struct node* new)
+{
+ new->prev=l->head.prev;
+ new->next=&l->head;
+ l->head.prev->next=new;
+ l->head.prev=new;
+}
+
+void
+list_add_after(struct node* orig, struct node* new)
+{
+ new->prev=orig;
+ new->next=orig->next;
+ orig->next->prev=new;
+ orig->next=new;
+}
+
+void
+list_add_before(struct node* orig, struct node* new)
+{
+ new->prev=orig->prev;
+ new->next=orig;
+ orig->prev->next=new;
+ orig->prev=new;
+}
+
+void
+list_del_node(struct node* n)
+{
+ n->prev->next=n->next;
+ n->next->prev=n->prev;
+ n->prev=n->next=NULL;
+}
+
+void*
+list_del_first(struct list* l)
+{
+ struct node* del;
+
+ if (list_is_empty(l))
+ return NULL;
+
+ del=l->head.next;
+ list_del_node(del);
+
+ return del;
+}
+
+void*
+list_del_last(struct list* l)
+{
+ struct node* del;
+
+ if (list_is_empty(l))
+ return NULL;
+
+ del=l->head.prev;
+ list_del_node(del);
+
+ return del;
+}
--- /dev/null
+struct node {
+ struct node* prev;
+ struct node* next;
+};
+
+struct list {
+ struct node head;
+};
+
+#define LIST_FOREACH(p,list) for(p=(void*)(list)->head.next; (struct node*)p!=&(list)->head; p=(void*)((struct node*) p)->next)
+void list_init(struct list* l);
+int list_is_empty(struct list* l);
+void* list_first(struct list* l);
+void* list_last(struct list* l);
+void* list_prev(struct list* l, struct node* n);
+void* list_next(struct list* l, struct node* n);
+void list_add_first(struct list* l, struct node* new);
+void list_add_last(struct list* l, struct node* new);
+void list_add_after(struct node* orig, struct node* new);
+void list_add_before(struct node* orig, struct node* new);
+void list_del_node(struct node* n);
+void* list_del_first(struct list* l);
+void* list_del_last(struct list* l);