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;
+}
+
+void rx_set_template(rx_t *rx, const char *tpl)
+{
+ const char *p = tpl;
+
+ m_strreplace(&rx->template, 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++;
+ }
+ }
+
+ rx->nmatch++; /* match 0 is always the whole expr */
}
-int rx_list_match(list2_t *l, const char *pat)
+void rx_wipe(rx_t *rx)
{
- int i;
+ p_delete(&rx->pattern);
+ regfree(rx->rx);
+ p_delete(&rx->rx);
+ p_delete(&rx->template);
+}
- if (!pat || !*pat || list_empty(l))
+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_lookup (list2_t *l, const char *pat)
+int rx_list_match2(rx_t *l, const char *s, char *dst, int dlen)
{
- int i;
+ 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->template, *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;
+ }
+ }
- if (!pat || !*pat || list_empty(l))
- return -1;
+ return 0;
+}
+
+rx_t **rx_lookup(rx_t **l, const char *pat)
+{
+ if (m_strisempty(pat))
+ return NULL;
- for (i = 0; i < l->length; i++) {
- if (!strcmp(((rx_t*)l->data[i])->pattern, pat))
- return i;
+ while (*l) {
+ if (!m_strcmp((*l)->pattern, pat))
+ return l;
+ l = &(*l)->next;
}
- return -1;
+ return NULL;
}
int rx_sanitize_string(char *dst, ssize_t n, const char *src)