diff options
Diffstat (limited to 'regc_locale.c')
| -rw-r--r-- | regc_locale.c | 55 |
1 files changed, 37 insertions, 18 deletions
diff --git a/regc_locale.c b/regc_locale.c index 97aa702..e55d5d7 100644 --- a/regc_locale.c +++ b/regc_locale.c @@ -120,16 +120,12 @@ static const struct cname { * Unicode character-class tables. */ -// FIXME: Perhaps define a new type here, similar to the -// original chr, so we don't waste space on the tables -// in ASCII (non-UTF-8) builds. -// Or perhaps pchr should just be like chr in the original implementation. typedef struct crange { pchr start; pchr end; } crange; -#if defined(REGEX_STANDALONE) && ! defined(REGEX_UTF8) +#if defined(REGEX_STANDALONE) && 0 //! defined(REGEX_UTF8) static const crange alphaRangeTable[] = { {0x41, 0x5a}, {0x61, 0x7a} @@ -221,6 +217,9 @@ static const pchr printCharTable[] = { * Declarations of Unicode character ranges. This code * is automatically generated by the tools/uniClass.tcl script * and used in generic/regc_locale.c. Do not modify by hand. + * + * Since this is a superset of ASCII, the same tables are used + * when matching with REG_RAW. */ /* Unicode: alphabetic characters */ @@ -724,17 +723,18 @@ element( assert(startp < endp); len = endp - startp; -#ifdef REGEX_UTF8 - wchar_t c; - if (mbtowc(&c, (const char *)startp, len) == len) { - // single character - return c; - } -#else - if (len == 1) { - return *startp; + + if (v->cflags & REG_RAW) { + if (len == 1) { + return *startp; + } + } else { + wchar_t c; + if (mbtowc(&c, (const char *)startp, len) == len) { + // single character + return c; + } } -#endif NOTE(REG_ULOCALE); @@ -1146,7 +1146,7 @@ cmp( } /* - - casecmp - case-independent chr-substring compare + - casecmp - case-independent Unicode-aware chr-substring compare * REG_ICASE backrefs need this. It should preferably be efficient. * Note that it does not need to report anything except equal/unequal. * Note also that the length is exact, and the comparison should not @@ -1158,9 +1158,28 @@ casecmp( const chr *x, const chr *y, /* strings to compare */ size_t len) /* exact length of comparison */ { + const chr *xp = x, *yp = y; + while (xp - x < len && yp - y < len) { + wchar_t xc, yc; + xp += mbtowc(&xc, (const char *)xp, len - (xp - x)); + yp += mbtowc(&yc, (const char *)yp, len - (yp - y)); + if (xc != yc && towlower(xc) != towlower(yc)) { + return 1; + } + } + return 0; +} + +/* + - casecmp_raw - case-independent byte-wise chr-substring compare + */ +static int /* 0 for equal, nonzero for unequal */ +casecmp_raw( + const chr *x, const chr *y, /* strings to compare */ + size_t len) /* exact length of comparison */ +{ for (; len > 0; len--, x++, y++) { - // FIXME: Will fail if REGEX_UTF8. - if ((*x!=*y) && (Tcl_UniCharToLower(*x) != Tcl_UniCharToLower(*y))) { + if ((*x!=*y) && (tolower(*x) != tolower(*y))) { return 1; } } |
