16 struct variable** res;
18 res = xmalloc (HASHSIZE * sizeof(struct variable*));
19 memset(res, 0, sizeof(struct variable*)*HASHSIZE);
25 get_bucket_number(char* name)
28 unsigned char* p = name;
31 n = n * MAGIC + toupper(*p++);
38 /* value NULL for finding without modyfiing */
39 static struct variable*
40 find_var(char* name, char* value, struct variable** hash)
45 n = get_bucket_number(name);
50 while(p && strcasecmp(p->name,name))
53 while(p && strcmp(p->name,name))
61 } else if (p && !value)
64 p = xmalloc(sizeof(struct variable));
68 p->value = (value? value:xstrdup(""));
76 regex_cmp(char* s, char* r)
81 int ovector[OVECCOUNT];
83 brum = pcre_compile(r,0,&error,&erroroffset,NULL);
87 int res = pcre_exec(brum,NULL,s,strlen(s),0,0,ovector,OVECCOUNT);
94 print_tree(struct tree* t, int ind)
101 printf("%*s if\n", ind, "");
102 print_tree(t->pt.tif.c,ind+1);
103 printf("%*s then\n", ind, "");
104 print_tree(t->pt.tif.i,ind+1);
105 printf("%*s else\n", ind, "");
106 print_tree(t->pt.tif.e,ind+1);
109 #define UPPER(a) ((a) >> 8)
110 #define LOWER(a) ((a) & 0xFF)
111 print_tree(t->pt.cond.left, ind+1);
112 printf("%*s", ind, "");
113 if (UPPER(t->pt.cond.op) > 0)
114 putchar(UPPER(t->pt.cond.op));
115 putchar(LOWER(t->pt.cond.op));
117 print_tree(t->pt.cond.right, ind+1);
120 print_tree(t->pt.block.head,ind);
121 print_tree(t->pt.block.tail,ind);
124 print_tree(t->pt.ass.left, ind+1);
125 printf("%*s =\n", ind, "");
126 print_tree(t->pt.ass.right, ind+1);
129 printf("%*s", ind, "");
130 switch (t->pt.leaf.type){
134 puts(t->pt.leaf.value);
139 if (t->pt.arrow.kw_left)
140 printf("%*s%s\n", ind+1, "", t->pt.arrow.kw_left);
141 printf("%*s ->\n", ind, "");
142 if (t->pt.arrow.kw_right)
143 printf("%*s%s\n", ind+1, "", t->pt.arrow.kw_right);
145 print_tree(t->pt.arrow.s,ind+1);
148 print_tree(t->pt.op.left, ind+1);
149 printf("%*s%c\n", ind, "", t->pt.op.op);
150 print_tree(t->pt.op.right, ind+1);
160 xcat(char* left, char* right)
162 char* res = xmalloc(strlen(left) + strlen(right) + 1);
174 interp_ass_right(struct tree* t, struct variable** hash)
178 if (t->pt.leaf.type == L_VAR)
179 return xstrdup(find_var(t->pt.leaf.value,NULL,hash)->value);
181 return xstrdup(t->pt.leaf.value);
183 switch (t->pt.op.op){
185 return xcat(interp_ass_right(t->pt.op.left, hash),interp_ass_right(t->pt.op.right, hash));
190 die("interp_ass_right: got to default");
194 // FIXME: we would like to be able also do things like ($a & $b) == $c
196 interp_cond(struct tree* t, struct variable** hash)
198 if (t->st != ST_COND)
199 die("Muhehehechlemst?");
201 if (t->pt.cond.type == OP_REL){
202 if (t->pt.cond.left->st != ST_LEAF || t->pt.cond.right->st != ST_LEAF)
205 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);
206 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);
207 switch (t->pt.cond.op){
209 return !strcmp(left,right);
211 return strcmp(left,right);
213 return regex_cmp(left,right);
215 return !regex_cmp(left,right);
216 } //TODO: add numbers
219 int left = interp_cond(t->pt.cond.left, hash);
222 if (t->pt.cond.op != '!')
223 right = interp_cond(t->pt.cond.right, hash);
225 switch (t->pt.cond.op){
227 return left && right;
229 return left || right;
231 return (left || right) && !(left && right);
239 modify_headers(struct hlist* headers, struct variable** hash)
242 struct hlist* last = NULL;
246 for(p = headers; p; p = p->next){
247 pv = find_var(p->name,NULL,hash);
251 pv->value = xstrdup(p->value); //FIXME: fold it
256 /* find new headers */
257 for (i = 0; i < HASHSIZE; i++){
258 for(pv = hash[i]; pv; pv = pv->next){
259 if (isupper(pv->name[0]) && pv->modified){
261 p = xmalloc(sizeof(struct hlist));
263 last->next = p; //FIXME
265 p->name = xstrdup(pv->name);
266 p->value = xstrdup(pv->value);
273 copy_headers(struct hlist* orig)
275 struct hlist* new = NULL;
276 struct hlist* po, * pn = NULL;
278 for (po = orig; po; po = po->next){
280 pn = xmalloc(sizeof(struct hlist));
281 pn->next = xmalloc(sizeof(struct hlist));
284 pn->name = xstrdup(po->name);
285 pn->value = xstrdup(po->value);
294 new_action(char* l, char* r, char* s, struct variable** hash)
298 a = xmalloc(sizeof(struct action));
300 modify_headers(current_headers, hash);
301 a->e.headers = copy_headers(current_headers);
310 interp(struct tree* t, struct variable** hash)
317 interp(t->pt.block.head, hash);
318 interp(t->pt.block.tail, hash);
321 find_var(t->pt.ass.left->pt.leaf.value, interp_ass_right(t->pt.ass.right, hash), hash);
324 if (interp_cond(t->pt.tif.c, hash))
325 interp(t->pt.tif.i, hash);
327 interp(t->pt.tif.e, hash);
330 new_action(t->pt.arrow.kw_left, t->pt.arrow.kw_right, interp_ass_right(t->pt.arrow.s, hash),hash);
335 die("interp: got to default");
341 print_vars(struct variable** hash)
346 for (i=0; i<HASHSIZE; i++){
349 printf("%s=%s\n",p->name, p->value);
362 new = xmalloc(strlen(u)+1);
365 #define IS_WHITE(c) ((c) == '\t' || (c)==' ' || c=='\n')
367 while (IS_WHITE(*pu))
372 while (IS_WHITE(*pu))
385 save_current_headers(struct variable** hash)
391 for (p = current_headers;p;p = p->next){
392 u = unfold(p->value);
393 pv = find_var(p->name,u,hash);