wmii

git clone git://oldgit.suckless.org/wmii/
Log | Files | Refs | README | LICENSE

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