From 8f3f7dcb5e25af426cb1be7c3f83edd7aab5d2f7 Mon Sep 17 00:00:00 2001 From: ketmar Date: Sat, 18 Feb 2012 15:39:26 +0200 Subject: [PATCH] HaveRule/HaveActions now works with globs and regexps --- src/builtins.c | 79 ++++++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 71 insertions(+), 8 deletions(-) diff --git a/src/builtins.c b/src/builtins.c index 971688d..ae29674 100644 --- a/src/builtins.c +++ b/src/builtins.c @@ -568,14 +568,13 @@ typedef struct { typedef struct { const char *str; int wantAction; + int casesens; } HRNormalData; static int hr_normal (const void *hdata, void *udata) { const RULE *r = (const RULE *)hdata; const HRNormalData *d = (const HRNormalData *)udata; // - //fprintf(stderr, "[%s]\n", r->name); - //if (r->name == NULL) return 0; if (strcasecmp(r->name, d->str) == 0) { if (d->wantAction && r->actions) return 1; // got it if (!d->wantAction && r->procedure) return 1; // got it @@ -583,6 +582,37 @@ static int hr_normal (const void *hdata, void *udata) { return 0; } +static int hr_glob (const void *hdata, void *udata) { + const RULE *r = (const RULE *)hdata; + const HRNormalData *d = (const HRNormalData *)udata; + // + if (matchglobex(d->str, r->name, d->casesens) == 0) { + //fprintf(stderr, ":[%s]\n", r->name); + if (d->wantAction && r->actions) return 1; // got it + if (!d->wantAction && r->procedure) return 1; // got it + } + return 0; +} + + +typedef struct { + HSRegExp re; + HSRxMatch *mt; + int wantAction; +} HRREData; + +static int hr_regexp (const void *hdata, void *udata) { + const RULE *r = (const RULE *)hdata; + HRREData *d = (HRREData *)udata; + // + if (hsrxExec(&d->re, r->name, d->re.re_nsub+1, d->mt, 0) == HSRX_NOERROR) { + //fprintf(stderr, ":[%s]\n", r->name); + if (d->wantAction && r->actions) return 1; // got it + if (!d->wantAction && r->procedure) return 1; // got it + } + return 0; +} + static LIST *builtin_haveruleactions (PARSE *parse, LOL *args, int *jmp) { LIST *el = lol_get(args, 0), *l; @@ -616,21 +646,54 @@ static LIST *builtin_haveruleactions (PARSE *parse, LOL *args, int *jmp) { } } else if (cmptype < 0) { // glob + HRNormalData nfo; + // + nfo.wantAction = wantAction; + nfo.casesens = casesens; + // + for (; el; el = el->next) { + // + nfo.str = el->string; + if (!iteraterules(hr_glob, &nfo)) return L0; + } } else if (cmptype > 0) { // regexp + HRREData nfo; + // + nfo.wantAction = wantAction; + // + for (; el; el = el->next) { + int err; + // + if ((err = hsrxCompile(&nfo.re, el->string, HSRX_EXTENDED | (casesens ? 0 : HSRX_ICASE))) != 0) { + static char errbuf[512]; + // + hsrxError(err, &nfo.re, errbuf, sizeof(errbuf)); + hsrxFree(&nfo.re); + printf("FATAL: invalid regexp in Have%s: %s\n", wantAction?"Actions":"Rule", errbuf); + exit(42); + } + nfo.mt = malloc(sizeof(HSRxMatch)*(nfo.re.re_nsub+1)); + if (nfo.mt == NULL) { + printf("FATAL: out of memory in Have%s.\n", wantAction?"Actions":"Rule"); + exit(42); + } + err = iteraterules(hr_regexp, &nfo); + free(nfo.mt); + hsrxFree(&nfo.re); + if (!err) return L0; + } } else { // normal, case-insensitive + HRNormalData nfo; + // + nfo.wantAction = wantAction; + // for (; el; el = el->next) { - HRNormalData nfo; - // nfo.str = el->string; - nfo.wantAction = wantAction; - fprintf(stderr, "?: [%s]\n", el->string); if (!iteraterules(hr_normal, &nfo)) return L0; - fprintf(stderr, "!: [%s]\n", el->string); } } - fprintf(stderr, "OK\n"); return list_new(L0, "1", 0); } -- 2.11.4.GIT