diff options
Diffstat (limited to 'src/match_regex.c')
-rw-r--r-- | src/match_regex.c | 61 |
1 files changed, 61 insertions, 0 deletions
diff --git a/src/match_regex.c b/src/match_regex.c new file mode 100644 index 0000000..fc666c9 --- /dev/null +++ b/src/match_regex.c @@ -0,0 +1,61 @@ +#include "genrc.h" + +static char * +progname_pattern(char const *prog) +{ + grecs_txtacc_t acc; + char *ret; + static char const specials[] = "\\[]?.*+(){}|"; + + acc = grecs_txtacc_create(); + grecs_txtacc_grow_char(acc, '^'); + if (prog[0] != '/') + grecs_txtacc_grow_string(acc, "(/(.*/)?)?"); + for (; *prog; prog++) { + if (strchr(specials, *prog)) + grecs_txtacc_grow_char(acc, '\\'); + grecs_txtacc_grow_char(acc, *prog); + } + grecs_txtacc_grow_char(acc, '$'); + grecs_txtacc_grow_char(acc, 0); + ret = grecs_txtacc_finish(acc, 1); + grecs_txtacc_free(acc); + return ret; +} + +void +match_regex_init(PROCSCANBUF buf, char const *pattern) +{ + regex_t *rx = xmalloc(sizeof(*rx)); + int rc; + char *tmp = NULL; + int cflags = REG_EXTENDED|REG_NOSUB; + if (buf->flags & PROCF_ICASE) + cflags |= REG_ICASE; + if (!pattern) { + pattern = tmp = progname_pattern(genrc_program); + } + + rc = regcomp(rx, pattern, cflags); + free(tmp); + if (rc) { + char errbuf[512]; + regerror(rc, rx, errbuf, sizeof(errbuf)); + usage_error("invalid regular expression: %s", errbuf); + } + buf->pattern = rx; +} + +void +match_regex_free(PROCSCANBUF buf) +{ + regfree((regex_t*)buf->pattern); + free(buf->pattern); +} + +int +match_regex(PROCSCANBUF buf, char const *arg) +{ + return regexec((regex_t*)buf->pattern, arg, 0, NULL, 0); +} + |