/** * Compiles all the given regexs. Returns 0 on success, * else an error code. */ int compile_regexs(Regex_node *re, Dictionary dict) { regex_t *preg; int rc; while (re != NULL) { /* If re->re non-null, assume compiled already. */ if(re->re == NULL) { /* Compile with default options (0) and default character * tables (NULL). */ /* re->re = pcre_compile(re->pattern, 0, &error, &erroroffset, NULL); */ preg = (regex_t *) malloc (sizeof(regex_t)); re->re = preg; rc = regcomp(preg, re->pattern, REG_EXTENDED); if (rc) { prt_regerror("Failed to compile regex", re, rc); return rc; } /* Check that the regex name is defined in the dictionary. */ if ((NULL != dict) && !boolean_dictionary_lookup(dict, re->name)) { /* TODO: better error handing. Maybe remove the regex? */ prt_error("Error: Regex name %s not found in dictionary!\n", re->name); } } re = re->next; } return 0; }
/** * Compile all the given regexs. * Return 0 on success, else an error code. */ int compile_regexs(Regex_node *rn, Dictionary dict) { while (rn != NULL) { /* If rn->re non-null, assume compiled already. */ if(rn->re == NULL) { int rc; regex_t *re = rn->re = malloc(sizeof(regex_t)); #if HAVE_PCRE2_H PCRE2_SIZE erroffset; re->re_code = pcre2_compile((PCRE2_SPTR)rn->pattern, PCRE2_ZERO_TERMINATED, PCRE2_UTF|PCRE2_UCP, &rc, &erroffset, NULL); if (NULL != re->re_code) { rc = 0; re->re_md = pcre2_match_data_create(0, NULL); if (NULL == re->re_md) return -1; /* Unhandled for now. */ } #else const int erroffset = -1; /* REG_ENHANCED is needed for macOS to support \w etc. */ #ifndef REG_ENHANCED #define REG_ENHANCED 0 #endif rc = regcomp(re, rn->pattern, REG_NOSUB|REG_EXTENDED|REG_ENHANCED); #endif if (rc) { prt_regerror("Failed to compile regex", rn, rc ,erroffset); rn->re = NULL; return rc; } /* Check that the regex name is defined in the dictionary. */ if ((NULL != dict) && !boolean_dictionary_lookup(dict, rn->name)) { /* TODO: better error handing. Maybe remove the regex? */ prt_error("Error: Regex name %s not found in dictionary!\n", rn->name); } } rn = rn->next; } return 0; }
const char *match_regex(const Regex_node *rn, const char *s) { while (rn != NULL) { int rc; bool nomatch; bool match; regex_t *re = rn->re; /* Make sure the regex has been compiled. */ assert(re); #if HAVE_PCRE2_H rc = pcre2_match(re->re_code, (PCRE2_SPTR)s, PCRE2_ZERO_TERMINATED, /*startoffset*/0, PCRE2_NO_UTF_CHECK, re->re_md, NULL); match = (rc >= 0); nomatch = (rc == PCRE2_ERROR_NOMATCH); #else rc = regexec(rn->re, s, 0, NULL, /*eflags*/0); match = (rc == 0); nomatch = (rc == REG_NOMATCH); #endif if (match) { lgdebug(+D_MRE, "%s%s %s\n", &"!"[!rn->neg], rn->name, s); if (!rn->neg) return rn->name; /* Match found - return--no multiple matches. */ /* Negative match - skip this regex name. */ for (const char *nre_name = rn->name; rn->next != NULL; rn = rn->next) { if (strcmp(nre_name, rn->next->name) != 0) break; } } else if (!nomatch) { /* We have an error. */ prt_regerror("Regex matching error", rn, rc, -1); } rn = rn->next; } return NULL; /* No matches. */ }
const char *match_regex(const Regex_node *re, const char *s) { int rc; const char *nre_name; while (re != NULL) { if (re->re == NULL) { /* Re not compiled; if this happens, it's likely an * internal error, but nevermind for now. */ continue; } /* Try to match with no extra data (NULL), whole str (0 to strlen(s)), * and default options (second 0). */ /* int rc = pcre_exec(re->re, NULL, s, strlen(s), 0, * 0, ovector, PCRE_OVEC_SIZE); */ rc = regexec((regex_t*) re->re, s, 0, NULL, 0); if (0 == rc) { lgdebug(+D_MRE, "%s%s %s\n", &"!"[!re->neg], re->name, s); if (!re->neg) return re->name; /* Match found - return--no multiple matches. */ /* Negative match - skip this regex name. */ for (nre_name = re->name; re->next != NULL; re = re->next) { if (strcmp(nre_name, re->next->name) != 0) break; } } else if (rc != REG_NOMATCH) { /* We have an error. */ prt_regerror("Regex matching error", re, rc); } re = re->next; } return NULL; /* No matches. */ }