CLEANUP: regex: Create regex_comp function that compiles regex using compilation options

The current file "regex.h" define an abstraction for the regex. It
provides the same struct name and the same "regexec" function for the
3 regex types supported: standard libc, basic pcre and jit pcre.

The regex compilation function is not provided by this file. If the
developper wants to use regex, he must write regex compilation code
containing "#define *JIT*".

This patch provides a unique regex compilation function according to
the compilation options.

In addition, the "regex.h" file checks the presence of the "#define
PCRE_CONFIG_JIT" when "USE_PCRE_JIT" is enabled. If this flag is not
present, the pcre lib doesn't support JIT and "#error" is emitted.
This commit is contained in:
Thierry FOURNIER 2013-10-14 14:07:36 +02:00 committed by Willy Tarreau
parent e68e02dc1d
commit ed5a4aefae
3 changed files with 53 additions and 27 deletions

View File

@ -31,6 +31,9 @@
#include <pcreposix.h> #include <pcreposix.h>
#ifdef USE_PCRE_JIT #ifdef USE_PCRE_JIT
#ifndef PCRE_CONFIG_JIT
#error "The PCRE lib doesn't support JIT. Change your lib, or remove the option USE_PCRE_JIT."
#endif
struct jit_regex { struct jit_regex {
pcre *reg; pcre *reg;
pcre_extra *extra; pcre_extra *extra;
@ -64,6 +67,17 @@ struct hdr_exp {
extern regmatch_t pmatch[MAX_MATCH]; extern regmatch_t pmatch[MAX_MATCH];
/* "str" is the string that contain the regex to compile.
* "regex" is preallocated memory. After the execution of this function, this
* struct contain the compiled regex.
* "cs" is the case sensitive flag. If cs is true, case sensitive is enabled.
* "cap" is capture flag. If cap if true the regex can capture into
* parenthesis strings.
* "err" is the standar error message pointer.
*
* The function return 1 is succes case, else return 0 and err is filled.
*/
int regex_comp(const char *str, regex *regex, int cs, int cap, char **err);
int exp_replace(char *dst, char *src, const char *str, const regmatch_t *matches); int exp_replace(char *dst, char *src, const char *str, const regmatch_t *matches);
const char *check_replace_string(const char *str); const char *check_replace_string(const char *str);
const char *chain_regex(struct hdr_exp **head, const regex_t *preg, const char *chain_regex(struct hdr_exp **head, const regex_t *preg,

View File

@ -543,11 +543,6 @@ static void acl_free_reg(void *ptr)
int acl_parse_reg(const char **text, struct acl_pattern *pattern, int *opaque, char **err) int acl_parse_reg(const char **text, struct acl_pattern *pattern, int *opaque, char **err)
{ {
regex *preg; regex *preg;
int icase;
#ifdef USE_PCRE_JIT
const char *error;
int erroffset;
#endif
preg = calloc(1, sizeof(*preg)); preg = calloc(1, sizeof(*preg));
@ -556,32 +551,11 @@ int acl_parse_reg(const char **text, struct acl_pattern *pattern, int *opaque, c
return 0; return 0;
} }
#ifdef USE_PCRE_JIT if (!regex_comp(*text, preg, !(pattern->flags & ACL_PAT_F_IGNORE_CASE), 0, err)) {
icase = (pattern->flags & ACL_PAT_F_IGNORE_CASE) ? PCRE_CASELESS : 0;
preg->reg = pcre_compile(*text, PCRE_NO_AUTO_CAPTURE | icase, &error, &erroffset,
NULL);
if (!preg->reg) {
free(preg); free(preg);
memprintf(err, "regex '%s' is invalid (error=%s, erroffset=%d)", *text, error, erroffset);
return 0; return 0;
} }
preg->extra = pcre_study(preg->reg, PCRE_STUDY_JIT_COMPILE, &error);
if (!preg->extra) {
pcre_free(preg->reg);
free(preg);
memprintf(err, "failed to compile regex '%s' (error=%s)", *text, error);
return 0;
}
#else
icase = (pattern->flags & ACL_PAT_F_IGNORE_CASE) ? REG_ICASE : 0;
if (regcomp(preg, *text, REG_EXTENDED | REG_NOSUB | icase) != 0) {
free(preg);
memprintf(err, "regex '%s' is invalid", *text);
return 0;
}
#endif
pattern->ptr.reg = preg; pattern->ptr.reg = preg;
pattern->freeptrbuf = &acl_free_reg; pattern->freeptrbuf = &acl_free_reg;
return 1; return 1;

View File

@ -122,7 +122,45 @@ const char *chain_regex(struct hdr_exp **head, const regex_t *preg,
return NULL; return NULL;
} }
int regex_comp(const char *str, regex *regex, int cs, int cap, char **err)
{
#ifdef USE_PCRE_JIT
int flags = 0;
const char *error;
int erroffset;
if (!cs)
flags |= PCRE_CASELESS;
if (!cap)
flags |= PCRE_NO_AUTO_CAPTURE;
regex->reg = pcre_compile(str, flags, &error, &erroffset, NULL);
if (!regex->reg) {
memprintf(err, "regex '%s' is invalid (error=%s, erroffset=%d)", str, error, erroffset);
return 0;
}
regex->extra = pcre_study(regex->reg, PCRE_STUDY_JIT_COMPILE, &error);
if (!regex->extra) {
pcre_free(regex->reg);
memprintf(err, "failed to compile regex '%s' (error=%s)", str, error);
return 0;
}
#else
int flags = REG_EXTENDED;
if (!cs)
flags |= REG_ICASE;
if (!cap)
flags |= REG_NOSUB;
if (regcomp(regex, str, flags) != 0) {
memprintf(err, "regex '%s' is invalid", str);
return 0;
}
#endif
return 1;
}
/* /*
* Local variables: * Local variables: