CFLAGS=-Wall -W -Wno-pointer-sign -O2 -g
LDLIBS=-lpcre
-brum: brum.c cond.tab.o int.o lex.o
+brum: brum.c cond.tab.o int.o lex.o ham.o
gcc -o $@ $^ $(LDLIBS)
cond.tab.o: cond.tab.c lex.o
int.o: int.c
+ham.o: ham.c
+
cond.tab.c: cond.y
bison -dvt cond.y
#include "brum.h"
int
-main(void)
+main(int argc, char** argv)
{
int res;
+ if (argc < 2)
+ die("Usage: ./brum conf_file");
+
+ read_conf(argv[1]);
+
// yydebug=1;
res = yyparse ();
print_tree(input_tree,0);
var_hash = new_var_hash();
+
+ current_headers = make_hlist();
+// print_headers(current_headers);
+
+ save_current_headers(var_hash);
interp(input_tree, var_hash);
print_vars(var_hash);
void* xmalloc(size_t size);
char* xstrdup(char* s);
void __attribute__ ((noreturn)) die(char* msg, ...);
+void read_conf(char* filename);
int line;
+FILE* conf;
/* int.c */
struct variable {
struct variable* next;
};
+struct hlist {
+ char* name;
+ char* value;
+ struct hlist* next;
+};
+
struct variable** var_hash;
void print_tree(struct tree* t, int ind);
void interp(struct tree* t, struct variable** hash);
struct variable** new_var_hash(void);
void print_vars(struct variable** hash);
+void save_current_headers(struct variable** hash);
+
+/* ham.c */
+struct hlist* current_headers;
+struct hlist* make_hlist();
+void print_headers();
%token <str> CONST
%token <n> NUM
%token <str> VAR
+%token <str> KW_DISCARD
%token <str> KW_PIPE KW_MAIL KW_COPY
%token '(' ')' '{' '}' ';'
%nonassoc KW_IF
$$->pt.arrow.kw_left = $1;
$$->pt.arrow.kw_right = $3;
}
+ | left ARROW KW_DISCARD { //FIXME: actually left does not make sense here
+ $$ = tree_malloc(ST_ARROW);
+ $$->pt.arrow.s = NULL;
+ $$->pt.arrow.kw_left = NULL;
+ $$->pt.arrow.kw_right = "discard";
+ }
;
left: /* empty */ { $$ = NULL;}
#include <stdio.h>
#include <string.h>
#include <pcre.h>
+#include <ctype.h>
#include "cond.tab.h"
#include "brum.h"
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];
p = xmalloc(sizeof(struct variable));
p->next = hash[n];
hash[n] = p;
- p->name = xstrdup(name);
+ p->name = name;
p->value = (value? value:xstrdup(""));
}
printf("%*s ->\n", ind, "");
if (t->pt.arrow.kw_right)
printf("%*s%s\n", ind+1, "", t->pt.arrow.kw_right);
- print_tree(t->pt.arrow.s,ind+1);
+ if (t->pt.arrow.s)
+ print_tree(t->pt.arrow.s,ind+1);
break;
case ST_OP:
print_tree(t->pt.op.left, ind+1);
}
}
+// FIXME: we would like to be able also do things like ($a & $b) == $c
int
interp_cond(struct tree* t, struct variable** hash)
{
if (t->pt.cond.type == OP_REL){
if (t->pt.cond.left->st != ST_LEAF || t->pt.cond.right->st != ST_LEAF)
- die("Chlemst");
+ die("Chlemst");
char* left = (t->pt.cond.left->pt.leaf.type == L_VAR ? find_var(t->pt.cond.left->pt.leaf.value,NULL,hash)->value : t->pt.cond.left->pt.leaf.value);
char* right = (t->pt.cond.right->pt.leaf.type == L_VAR ? find_var(t->pt.cond.right->pt.leaf.value,NULL,hash)->value : t->pt.cond.right->pt.leaf.value);
return regex_cmp(left,right);
case CC('!','~'):
return !regex_cmp(left,right);
- }
+ } //TODO: add numbers
} else {
int left = interp_cond(t->pt.cond.left, hash);
}
}
+void
+new_action(char* l, char* r, char* s)
+{
+ //TODO: modify headers according to variable values
+}
+
void
interp(struct tree* t, struct variable** hash)
{
else
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));
+ break;
case ST_EMPTY:
break;
default:
}
}
}
+
+static char*
+unfold(char* u)
+{
+ char* new;
+ char* pu = u;
+ char* pn;
+
+ new = xmalloc(strlen(u)+1);
+ pn = new;
+
+#define IS_WHITE(c) ((c) == '\t' || (c)==' ' || c=='\n')
+
+ while (IS_WHITE(*pu))
+ pu++;
+
+ while (*pu != 0){
+ if (IS_WHITE(*pu)){
+ while (IS_WHITE(*pu))
+ pu++;
+ if (*pu != 0)
+ *pn++ = ' ';
+ } else
+ *pn++ = *pu++;
+ }
+ *pn = 0;
+
+ return new;
+}
+
+void
+save_current_headers(struct variable** hash)
+{
+ struct hlist* p;
+ char* u;
+
+ for (p = current_headers;p;p = p->next){
+ u = unfold(p->value);
+ find_var(p->name,u,hash);
+ }
+
+}
{"else", KW_ELSE},
{"if", KW_IF},
{"mail", KW_MAIL},
- {"pipe", KW_PIPE}
+ {"pipe", KW_PIPE},
+ {"discard", KW_DISCARD}
};
+void
+read_conf(char* filename)
+{
+ conf = fopen(filename, "r");
+
+ if (! conf)
+ die("read_conf: %m");
+}
+
void __attribute__ ((noreturn))
die(char* msg, ...)
{
int c;
char buf[BUFSIZE];
- while ((c = getchar()) != delim || last == '\\'){
+ while ((c = getc(conf)) != delim || last == '\\'){
if (last=='\\' && c != delim)
buf[i-1] = c;
else {
{
int c;
- while ((c = getchar ()) == ' ' || c == '\t' || c =='\n'){
+ while ((c = getc(conf)) == ' ' || c == '\t' || c =='\n'){
if (c == '\n')
line++;
}
if (c == EOF)
return 0;
- int d = getchar();
+ int d = getc(conf);
if (d >= 0) {
switch (CC(c,d)) {
case CC('!','='): yylval.n = CC('!','='); return NEQ;
case CC('~','~'): yylval.n = CC('~','~'); return RE;
case CC('-','>'): yylval.n = CC('-','>'); return ARROW;
}
- ungetc(d,stdin);
+ ungetc(d,conf);
}
switch (c) {
}
if (c >= '0' && c <= '9'){
- ungetc(c,stdin);
+ ungetc(c,conf);
int i = 0;
char buf[BUFSIZE];
- while ((c = getchar())>= '0' && c<= '9'){
+ while ((c = getc(conf))>= '0' && c<= '9'){
buf[i] = c;
i++;
if (i >= BUFSIZE-1)
parse_err("Too long number");
}
- ungetc(c,stdin);
+ ungetc(c,conf);
buf[i] = 0;
yylval.str = xstrdup(buf);
int i = 0;
char buf[BUFSIZE];
- while (is_var_id(c = getchar())){
+ while (is_var_id(c = getc(conf))){
buf[i]=c;
i++;
if (i >= BUFSIZE-1)
parse_err("Too long identifier, max allowed length is %d",BUFSIZE-1);
}
- ungetc(c,stdin);
+ ungetc(c,conf);
buf[i] = 0;
yylval.str = xstrdup(buf);
char buf[KLEN];
int n, i = 0;
- ungetc(c,stdin);
- while (is_alpha(c = getchar())){
+ ungetc(c,conf);
+ while (is_alpha(c = getc(conf))){
buf[i++] = c;
if (i >= KLEN)
parse_err("Keyword too long");
}
buf[i] = 0;
- ungetc(c,stdin);
+ ungetc(c,conf);
n = (sizeof(kwds)/sizeof(struct keys));
for (i = 0; i < n; i++){