Index: user/gabor/tre-integration/contrib/tre/lib/regcomp.c =================================================================== --- user/gabor/tre-integration/contrib/tre/lib/regcomp.c (revision 225589) +++ user/gabor/tre-integration/contrib/tre/lib/regcomp.c (revision 225590) @@ -1,160 +1,155 @@ /* tre_regcomp.c - TRE POSIX compatible regex compilation functions. This software is released under a BSD-style license. See the file LICENSE for details and copyright. */ #ifdef HAVE_CONFIG_H #include #endif /* HAVE_CONFIG_H */ #include #include #include #include #include "tre-fastmatch.h" #include "tre-heuristic.h" #include "tre-internal.h" #include "xmalloc.h" #ifdef TRE_LIBC_BUILD __weak_reference(tre_regcomp, regcomp); __weak_reference(tre_regncomp, regncomp); __weak_reference(tre_regwcomp, regwcomp); __weak_reference(tre_regwncomp, regwncomp); __weak_reference(tre_regfree, regfree); #endif int tre_regncomp(regex_t *preg, const char *regex, size_t n, int cflags) { int ret; #if TRE_WCHAR tre_char_t *wregex; size_t wlen; wregex = xmalloc(sizeof(tre_char_t) * (n + 1)); if (wregex == NULL) return REG_ESPACE; /* If the current locale uses the standard single byte encoding of characters, we don't do a multibyte string conversion. If we did, many applications which use the default locale would break since the default "C" locale uses the 7-bit ASCII character set, and all characters with the eighth bit set would be considered invalid. */ #if TRE_MULTIBYTE if (TRE_MB_CUR_MAX == 1) #endif /* TRE_MULTIBYTE */ { unsigned int i; const unsigned char *str = (const unsigned char *)regex; tre_char_t *wstr = wregex; for (i = 0; i < n; i++) *(wstr++) = *(str++); wlen = n; } #if TRE_MULTIBYTE else { int consumed; tre_char_t *wcptr = wregex; #ifdef HAVE_MBSTATE_T mbstate_t state; memset(&state, '\0', sizeof(state)); #endif /* HAVE_MBSTATE_T */ while (n > 0) { consumed = tre_mbrtowc(wcptr, regex, n, &state); switch (consumed) { case 0: if (*regex == '\0') consumed = 1; else { xfree(wregex); return REG_BADPAT; } break; case -1: DPRINT(("mbrtowc: error %d: %s.\n", errno, strerror(errno))); xfree(wregex); return REG_BADPAT; case -2: /* The last character wasn't complete. Let's not call it a fatal error. */ consumed = n; break; } regex += consumed; n -= consumed; wcptr++; } wlen = wcptr - wregex; } #endif /* TRE_MULTIBYTE */ wregex[wlen] = L'\0'; ret = tre_compile(preg, wregex, wlen, cflags); xfree(wregex); #else /* !TRE_WCHAR */ ret = tre_compile(preg, (const tre_char_t *)regex, n, cflags); #endif /* !TRE_WCHAR */ return ret; } int tre_regcomp(regex_t *preg, const char *regex, int cflags) { - size_t len; - - if (cflags & REG_PEND) - { - if (preg->re_endp >= regex) - len = preg->re_endp - regex; - else - len = regex ? strlen(regex) : 0; - return tre_regncomp(preg, regex, len, cflags); - } + if ((cflags & REG_PEND) && (preg->re_endp >= regex)) + return tre_regncomp(preg, regex, preg->re_endp - regex, cflags); else return tre_regncomp(preg, regex, regex ? strlen(regex) : 0, cflags); } #ifdef TRE_WCHAR int tre_regwncomp(regex_t *preg, const wchar_t *regex, size_t n, int cflags) { return tre_compile(preg, regex, n, cflags); } int tre_regwcomp(regex_t *preg, const wchar_t *regex, int cflags) { + if ((cflags & REG_PEND) && (preg->re_wendp >= regex)) + return tre_compile(preg, regex, preg->re_wendp - regex, cflags); + else return tre_compile(preg, regex, regex ? wcslen(regex) : 0, cflags); } #endif /* TRE_WCHAR */ void tre_regfree(regex_t *preg) { if (preg->shortcut != NULL) { tre_free_fast(preg->shortcut); xfree(preg->shortcut); } if (preg->heur != NULL) { tre_free_heur(preg->heur); xfree(preg->heur); } tre_free(preg); } /* EOF */ Index: user/gabor/tre-integration/include/regex.h =================================================================== --- user/gabor/tre-integration/include/regex.h (revision 225589) +++ user/gabor/tre-integration/include/regex.h (revision 225590) @@ -1,278 +1,281 @@ /* $FreeBSD$ */ /* tre.h - TRE public API definitions This software is released under a BSD-style license. See the file LICENSE for details and copyright. */ #ifndef REGEX_H #define REGEX_H 1 #include #define TRE_WCHAR 1 #define TRE_APPROX 1 #ifdef __cplusplus extern "C" { #endif #ifndef TRE_LIBC_BUILD #define tre_regcomp regcomp #define tre_regerror regerror #define tre_regexec regexec #define tre_regfree regfree #define tre_regacomp regacomp #define tre_regaexec regaexec #define tre_regancomp regancomp #define tre_reganexec reganexec #define tre_regawncomp regawncomp #define tre_regawnexec regawnexec #define tre_regncomp regncomp #define tre_regnexec regnexec #define tre_regwcomp regwcomp #define tre_regwexec regwexec #define tre_regwncomp regwncomp #define tre_regwnexec regwnexec #define FUNC_DECL(f) f #else #define regcomp tre_regcomp #define regerror tre_regerror #define regexec tre_regexec #define regfree tre_regfree #define regacomp tre_regacomp #define regaexec tre_regaexec #define regancomp tre_regancomp #define reganexec tre_reganexec #define regawncomp tre_regawncomp #define regawnexec tre_regawnexec #define regncomp tre_regncomp #define regnexec tre_regnexec #define regwcomp tre_regwcomp #define regwexec tre_regwexec #define regwncomp tre_regwncomp #define regwnexec tre_regwnexec #define FUNC_DECL(f) tre_##f #endif typedef int regoff_t; typedef struct { size_t re_nsub; /* Number of parenthesized subexpressions. */ void *value; /* For internal use only. */ void *shortcut; /* For internal use only. */ void *heur; /* For internal use only. */ const char *re_endp; +#ifdef TRE_WCHAR + const wchar_t *re_wendp; +#endif } regex_t; typedef struct { regoff_t rm_so; regoff_t rm_eo; } regmatch_t; typedef enum { REG_OK = 0, /* No error. */ /* POSIX tre_regcomp() return error codes. (In the order listed in the standard.) */ REG_NOMATCH, /* No match. */ REG_BADPAT, /* Invalid regexp. */ REG_ECOLLATE, /* Unknown collating element. */ REG_ECTYPE, /* Unknown character class name. */ REG_EESCAPE, /* Trailing backslash. */ REG_ESUBREG, /* Invalid back reference. */ REG_EBRACK, /* "[]" imbalance */ REG_EPAREN, /* "\(\)" or "()" imbalance */ REG_EBRACE, /* "\{\}" or "{}" imbalance */ REG_BADBR, /* Invalid content of {} */ REG_ERANGE, /* Invalid use of range operator */ REG_ESPACE, /* Out of memory. */ REG_BADRPT /* Invalid use of repetition operators. */ } reg_errcode_t; /* POSIX tre_regcomp() flags. */ #define REG_EXTENDED 1 #define REG_ICASE (REG_EXTENDED << 1) #define REG_NEWLINE (REG_ICASE << 1) #define REG_NOSUB (REG_NEWLINE << 1) /* Extra tre_regcomp() flags. */ #define REG_BASIC 0 #define REG_LITERAL (REG_NOSUB << 1) #define REG_RIGHT_ASSOC (REG_LITERAL << 1) #define REG_UNGREEDY (REG_RIGHT_ASSOC << 1) #define REG_PEND (REG_UNGREEDY << 1) #define REG_GNU (REG_PEND << 1) #define REG_WORD (REG_GNU << 1) /* POSIX tre_regexec() flags. */ #define REG_NOTBOL 1 #define REG_NOTEOL (REG_NOTBOL << 1) /* Extra tre_regexec() flags. */ #define REG_APPROX_MATCHER (REG_NOTEOL << 1) #define REG_BACKTRACKING_MATCHER (REG_APPROX_MATCHER << 1) #define REG_STARTEND (REG_BACKTRACKING_MATCHER << 1) /* REG_NOSPEC and REG_LITERAL mean the same thing. */ #if defined(REG_LITERAL) && !defined(REG_NOSPEC) #define REG_NOSPEC REG_LITERAL #elif defined(REG_NOSPEC) && !defined(REG_LITERAL) #define REG_LITERAL REG_NOSPEC #endif /* defined(REG_NOSPEC) */ /* The maximum number of iterations in a bound expression. */ #undef RE_DUP_MAX #define RE_DUP_MAX 255 /* The POSIX.2 regexp functions */ extern int FUNC_DECL(regcomp)(regex_t *preg, const char *regex, int cflags); extern int FUNC_DECL(regexec)(const regex_t *preg, const char *string, size_t nmatch, regmatch_t pmatch[], int eflags); extern size_t FUNC_DECL(regerror)(int errcode, const regex_t *preg, char *errbuf, size_t errbuf_size); extern void FUNC_DECL(regfree)(regex_t *preg); #ifdef TRE_WCHAR #include /* Wide character versions (not in POSIX.2). */ extern int FUNC_DECL(regwcomp)(regex_t *preg, const wchar_t *regex, int cflags); extern int FUNC_DECL(regwexec)(const regex_t *preg, const wchar_t *string, size_t nmatch, regmatch_t pmatch[], int eflags); #endif /* TRE_WCHAR */ /* Versions with a maximum length argument and therefore the capability to handle null characters in the middle of the strings (not in POSIX.2). */ extern int FUNC_DECL(regncomp)(regex_t *preg, const char *regex, size_t len, int cflags); extern int FUNC_DECL(regnexec)(const regex_t *preg, const char *string, size_t len, size_t nmatch, regmatch_t pmatch[], int eflags); #ifdef TRE_WCHAR extern int FUNC_DECL(regwncomp)(regex_t *preg, const wchar_t *regex, size_t len, int cflags); extern int FUNC_DECL(regwnexec)(const regex_t *preg, const wchar_t *string, size_t len, size_t nmatch, regmatch_t pmatch[], int eflags); #endif /* TRE_WCHAR */ #ifdef TRE_APPROX /* Approximate matching parameter struct. */ typedef struct { int cost_ins; /* Default cost of an inserted character. */ int cost_del; /* Default cost of a deleted character. */ int cost_subst; /* Default cost of a substituted character. */ int max_cost; /* Maximum allowed cost of a match. */ int max_ins; /* Maximum allowed number of inserts. */ int max_del; /* Maximum allowed number of deletes. */ int max_subst; /* Maximum allowed number of substitutes. */ int max_err; /* Maximum allowed number of errors total. */ } regaparams_t; /* Approximate matching result struct. */ typedef struct { size_t nmatch; /* Length of pmatch[] array. */ regmatch_t *pmatch; /* Submatch data. */ int cost; /* Cost of the match. */ int num_ins; /* Number of inserts in the match. */ int num_del; /* Number of deletes in the match. */ int num_subst; /* Number of substitutes in the match. */ } regamatch_t; /* Approximate matching functions. */ extern int FUNC_DECL(regaexec)(const regex_t *preg, const char *string, regamatch_t *match, regaparams_t params, int eflags); extern int FUNC_DECL(reganexec)(const regex_t *preg, const char *string, size_t len, regamatch_t *match, regaparams_t params, int eflags); #ifdef TRE_WCHAR /* Wide character approximate matching. */ extern int FUNC_DECL(regawexec)(const regex_t *preg, const wchar_t *string, regamatch_t *match, regaparams_t params, int eflags); extern int FUNC_DECL(regawnexec)(const regex_t *preg, const wchar_t *string, size_t len, regamatch_t *match, regaparams_t params, int eflags); #endif /* TRE_WCHAR */ /* Sets the parameters to default values. */ extern void tre_regaparams_default(regaparams_t *params); #endif /* TRE_APPROX */ #ifdef TRE_WCHAR typedef wchar_t tre_char_t; #else /* !TRE_WCHAR */ typedef unsigned char tre_char_t; #endif /* !TRE_WCHAR */ typedef struct { int (*get_next_char)(tre_char_t *c, unsigned int *pos_add, void *context); void (*rewind)(size_t pos, void *context); int (*compare)(size_t pos1, size_t pos2, size_t len, void *context); void *context; } tre_str_source; extern int FUNC_DECL(reguexec)(const regex_t *preg, const tre_str_source *string, size_t nmatch, regmatch_t pmatch[], int eflags); /* Returns the version string. The returned string is static. */ extern char * tre_version(void); /* Returns the value for a config parameter. The type to which `result' must point to depends of the value of `query', see documentation for more details. */ extern int tre_config(int query, void *result); enum { TRE_CONFIG_APPROX, TRE_CONFIG_WCHAR, TRE_CONFIG_MULTIBYTE, TRE_CONFIG_SYSTEM_ABI, TRE_CONFIG_VERSION }; /* Returns 1 if the compiled pattern has back references, 0 if not. */ extern int tre_have_backrefs(const regex_t *preg); /* Returns 1 if the compiled pattern uses approximate matching features, 0 if not. */ extern int tre_have_approx(const regex_t *preg); #ifdef __cplusplus } #endif #endif /* REGEX_H */ /* EOF */