X-Git-Url: http://git.madism.org/?p=apps%2Fmadmutt.git;a=blobdiff_plain;f=lib-lib%2Frx.c;h=d89d23468f5ed697e779ba30ee6edda329b5bfab;hp=6413f69c88fa81c9e4f962be07459986623a39ab;hb=717c9f150ded0fed572d27f68db07f94a9fe70e8;hpb=03fe827a7d4a7ad79ac235654414aa339a9a2c9a diff --git a/lib-lib/rx.c b/lib-lib/rx.c index 6413f69..d89d234 100644 --- a/lib-lib/rx.c +++ b/lib-lib/rx.c @@ -22,13 +22,7 @@ * please see the file GPL in the top level source directory. */ -#if HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include -#include +#include "lib-lib.h" rx_t *rx_compile(const char *s, int flags) { @@ -44,40 +38,172 @@ rx_t *rx_compile(const char *s, int flags) return pp; } -void rx_delete(rx_t **p) +int rx_validate(const char *s, char *errbuf, ssize_t errlen) { - p_delete(&(*p)->pattern); - regfree((*p)->rx); - p_delete(&(*p)->rx); - p_delete(p); + regex_t re; + int res; + + p_clear(&re, 1); + res = REGCOMP(&re, NONULL(s), 0); + if (res) { + regerror(res, &re, errbuf, errlen); + } + regfree(&re); + + return res; } -int rx_list_match(list2_t *l, const char *pat) +void rx_set_template(rx_t *rx, const char *tpl) { - int i; + const char *p = tpl; + + m_strreplace(&rx->tpl, tpl); + rx->nmatch = 0; + + while ((p = strchr(p, '%'))) { + if (isdigit(*++p)) { + int n = strtol(p, (char **)&p, 10); + rx->nmatch = MAX(n, rx->nmatch); + } else { + if (*p == '%') + p++; + } + } - if (!pat || !*pat || list_empty(l)) + rx->nmatch++; /* match 0 is always the whole expr */ +} + +void rx_wipe(rx_t *rx) +{ + p_delete(&rx->pattern); + regfree(rx->rx); + p_delete(&rx->rx); + p_delete(&rx->tpl); +} + +int rx_list_match(rx_t *l, const char *s) +{ + if (m_strisempty(s)) return 0; - for (i = 0; i < l->length; i++) { - if (!REGEXEC(((rx_t*)l->data[i])->rx, pat)) + while (l) { + if (!REGEXEC(l->rx, s)) + return 1; + l = l->next; + } + + return 0; +} + +int rx_list_match2(rx_t *l, const char *s, char *dst, int dlen) +{ + static regmatch_t *pmatch = NULL; + static int nmatch = 0; + int pos = 0; + + if (m_strisempty(s)) + return 0; + + for (; l; l = l->next) { + if (l->nmatch > nmatch) { + p_realloc(&pmatch, l->nmatch); + nmatch = l->nmatch; + } + + if (regexec(l->rx, s, l->nmatch, pmatch, 0) == 0) { + /* Copy template into dst, with substitutions. */ + const char *p = l->tpl, *q; + + for (q = strchr(p, '%'); q; q = strchr(p + 1, '%')) { + int n; + + pos += m_strncpy(dst + pos, dlen - pos, p, q - p); + + if (!isdigit((unsigned char)q[1])) { + p = q + (q[1] == '%'); + continue; + } + + n = strtol(q + 1, (char **)&p, 10); /* find pmatch index */ + pos += m_strncpy(dst + pos, dlen - pos, s + pmatch[n].rm_so, + pmatch[n].rm_eo - pmatch[n].rm_so); + } + + pos += m_strcpy(dst + pos, dlen - pos, p); return 1; + } } return 0; } -int rx_lookup (list2_t *l, const char *pat) +rx_t **rx_lookup(rx_t **l, const char *pat) { - int i; + if (m_strisempty(pat)) + return NULL; - if (!pat || !*pat || list_empty(l)) - return -1; + while (*l) { + if (!m_strcmp((*l)->pattern, pat)) + return l; + l = &(*l)->next; + } + + return l; +} - for (i = 0; i < l->length; i++) { - if (!strcmp(((rx_t*)l->data[i])->pattern, pat)) - return i; +void rx_list_add(rx_t **l, rx_t *rxp) +{ + l = rx_lookup(l, rxp->pattern); + if (*l) { + rx_t *r = rx_list_pop(l); + rx_delete(&r); + } + rx_list_push(l, rxp); +} + +void rx_list_add2(rx_t **l, rx_t **rxp) +{ + l = rx_lookup(l, (*rxp)->pattern); + if (*l) { + rx_t *r = rx_list_pop(l); + rx_delete(&r); + } + if (m_strisempty((*rxp)->tpl)) { + rx_delete(rxp); + } else { + rx_list_push(l, *rxp); } +} + +void rx_list_remove(rx_t **l, const rx_t *r) +{ + l = rx_lookup(l, r->pattern); + if (*l) { + rx_t *tmp = rx_list_pop(l); + rx_delete(&tmp); + } +} + +int rx_sanitize_string(char *dst, ssize_t n, const char *src) +{ + while (*src) { + if (n <= 1) + break; + + /* these characters must be escaped in regular expressions */ + if (strchr("^.[$()|*+?{\\", *src)) { + if (n <= 2) + break; + + *dst++ = '\\'; + n--; + } + + *dst++ = *src++; + n--; + } + + *dst = '\0'; - return -1; + return *src ? -1 : 0; }