aboutsummaryrefslogtreecommitdiff
path: root/regc_locale.c
diff options
context:
space:
mode:
Diffstat (limited to 'regc_locale.c')
-rw-r--r--regc_locale.c55
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;
}
}