rule.c (2113B)
1 /* Copyright ©2010 Kris Maglione <maglione.k at Gmail> 2 * See LICENSE file for license details. 3 */ 4 5 #include "dat.h" 6 #include "fns.h" 7 8 void 9 update_rules(Rule **rule, char *data) { 10 #define putc(m, c) BLOCK(if((m)->pos < (m)->end) *(m)->pos++ = c;) 11 #define getc(m) ((m)->pos < (m)->end ? *(m)->pos++ : 0) 12 #define ungetc(m) BLOCK(if((m)->pos > (m)->data) --(m)->pos) 13 14 IxpMsg buf, valuebuf, rebuf; 15 Reprog *re; 16 Rule *r; 17 Ruleval **rvp; 18 Ruleval *rv; 19 char *w; 20 char regexp[256]; 21 char c; 22 int len; 23 24 while((r = *rule)) { 25 *rule = r->next; 26 while((rv = r->values)) { 27 r->values = rv->next; 28 free(rv); 29 } 30 free(r->regex); 31 free(r->value); 32 free(r); 33 } 34 35 if(!data || !data[0]) 36 return; 37 38 buf = ixp_message(data, strlen(data), MsgUnpack); 39 40 begin: 41 msg_eatrunes(&buf, isspacerune, true); 42 if(getc(&buf) == '/') 43 goto regexp; 44 /* Regexp not at begining of the line. Rest of the line is junk. */ 45 while((c = getc(&buf))) 46 if(c == '\n') 47 goto begin; 48 goto done; 49 50 regexp: 51 rebuf = ixp_message(regexp, sizeof regexp - 1, MsgPack); 52 while((c = getc(&buf))) 53 if(c == '/') 54 goto value; 55 else if(c != '\\') 56 putc(&rebuf, c); 57 else if(buf.pos[1] == '/' || buf.pos[1] == '\\' && buf.pos[2] == '/') 58 putc(&rebuf, getc(&buf)); 59 else { 60 putc(&rebuf, c); 61 putc(&rebuf, getc(&buf)); 62 } 63 goto done; 64 65 value: 66 valuebuf = ixp_message(buffer, sizeof buffer - 1, MsgPack); 67 while((c = getc(&buf))) { 68 if(c == '\n') { 69 putc(&valuebuf, ' '); 70 msg_eatrunes(&buf, isspacerune, true); 71 if((c = getc(&buf)) == '/') { 72 ungetc(&buf); 73 break; 74 } 75 } 76 putc(&valuebuf, c); 77 } 78 79 putc(&rebuf, '\0'); 80 re = regcomp(regexp); 81 if(!re) 82 goto begin; 83 r = emallocz(sizeof *r); 84 *rule = r; 85 rule = &r->next; 86 r->regex = re; 87 88 valuebuf.end = valuebuf.pos; 89 valuebuf.pos = valuebuf.data; 90 rvp = &r->values; 91 while((w = msg_getword(&valuebuf, 0))) { 92 free(r->value); 93 r->value = estrdup(w); 94 if(strchr(w, '=')) { 95 len = strlen(w) + 1; 96 *rvp = rv = emallocz(sizeof *rv + len); 97 rvp = &rv->next; 98 99 memcpy(&rv[1], w, len); 100 tokenize(&rv->key, 2, (char*)&rv[1], '='); 101 } 102 } 103 goto begin; 104 105 done: 106 return; 107 } 108