Changeset View
Changeset View
Standalone View
Standalone View
lib/libc/regex/regcomp.c
Show First 20 Lines • Show All 126 Lines • ▼ Show 20 Lines | |||||
static int p_count(struct parse *p); | static int p_count(struct parse *p); | ||||
static void p_bracket(struct parse *p); | static void p_bracket(struct parse *p); | ||||
static int p_range_cmp(wchar_t c1, wchar_t c2); | static int p_range_cmp(wchar_t c1, wchar_t c2); | ||||
static void p_b_term(struct parse *p, cset *cs); | static void p_b_term(struct parse *p, cset *cs); | ||||
static void p_b_cclass(struct parse *p, cset *cs); | static void p_b_cclass(struct parse *p, cset *cs); | ||||
static void p_b_eclass(struct parse *p, cset *cs); | static void p_b_eclass(struct parse *p, cset *cs); | ||||
static wint_t p_b_symbol(struct parse *p); | static wint_t p_b_symbol(struct parse *p); | ||||
static wint_t p_b_coll_elem(struct parse *p, wint_t endc); | static wint_t p_b_coll_elem(struct parse *p, wint_t endc); | ||||
static wint_t othercase(wint_t ch); | static bool hasothercase(wint_t ch); | ||||
static void bothcases(struct parse *p, wint_t ch); | static void bothcases(struct parse *p, wint_t ch); | ||||
static void ordinary(struct parse *p, wint_t ch); | static void ordinary(struct parse *p, wint_t ch); | ||||
static void nonnewline(struct parse *p); | static void nonnewline(struct parse *p); | ||||
static void repeat(struct parse *p, sopno start, int from, int to); | static void repeat(struct parse *p, sopno start, int from, int to); | ||||
static int seterr(struct parse *p, int e); | static int seterr(struct parse *p, int e); | ||||
static cset *allocset(struct parse *p); | static cset *allocset(struct parse *p); | ||||
static void freeset(struct parse *p, cset *cs); | static void freeset(struct parse *p, cset *cs); | ||||
static void CHadd(struct parse *p, cset *cs, wint_t ch); | static void CHadd(struct parse *p, cset *cs, wint_t ch); | ||||
▲ Show 20 Lines • Show All 952 Lines • ▼ Show 20 Lines | p_b_coll_elem(struct parse *p, | ||||
else if (clen == (size_t)-1 || clen == (size_t)-2) | else if (clen == (size_t)-1 || clen == (size_t)-2) | ||||
SETERROR(REG_ILLSEQ); | SETERROR(REG_ILLSEQ); | ||||
else | else | ||||
SETERROR(REG_ECOLLATE); /* neither */ | SETERROR(REG_ECOLLATE); /* neither */ | ||||
return(0); | return(0); | ||||
} | } | ||||
/* | /* | ||||
- othercase - return the case counterpart of an alphabetic | * Check if alphabetic character has the other case mapping. | ||||
== static wint_t othercase(wint_t ch); | |||||
*/ | */ | ||||
static wint_t /* if no counterpart, return ch */ | static bool | ||||
othercase(wint_t ch) | hasothercase(wint_t ch) | ||||
{ | { | ||||
wint_t other; | |||||
assert(iswalpha(ch)); | assert(iswalpha(ch)); | ||||
other = ch; | |||||
if (iswupper(ch)) | if (iswupper(ch)) | ||||
return(towlower(ch)); | other = towlower(ch); | ||||
else if (iswlower(ch)) | else if (iswlower(ch)) | ||||
return(towupper(ch)); | other = towupper(ch); | ||||
else /* peculiar, but could happen */ | |||||
return(ch); | return (other != ch); | ||||
} | } | ||||
/* | /* | ||||
- bothcases - emit a dualcase version of a two-case character | - bothcases - emit a dualcase version of a two-case character | ||||
== static void bothcases(struct parse *p, wint_t ch); | == static void bothcases(struct parse *p, wint_t ch); | ||||
* | * | ||||
* Boy, is this implementation ever a kludge... | * Boy, is this implementation ever a kludge... | ||||
*/ | */ | ||||
static void | static void | ||||
bothcases(struct parse *p, wint_t ch) | bothcases(struct parse *p, wint_t ch) | ||||
{ | { | ||||
const char *oldnext = p->next; | const char *oldnext = p->next; | ||||
const char *oldend = p->end; | const char *oldend = p->end; | ||||
char bracket[3 + MB_LEN_MAX]; | char bracket[3 + MB_LEN_MAX]; | ||||
size_t n; | size_t n; | ||||
mbstate_t mbs; | mbstate_t mbs; | ||||
assert(othercase(ch) != ch); /* p_bracket() would recurse */ | assert(hasothercase(ch)); /* p_bracket() would recurse */ | ||||
p->next = bracket; | p->next = bracket; | ||||
memset(&mbs, 0, sizeof(mbs)); | memset(&mbs, 0, sizeof(mbs)); | ||||
n = wcrtomb(bracket, ch, &mbs); | n = wcrtomb(bracket, ch, &mbs); | ||||
assert(n != (size_t)-1); | assert(n != (size_t)-1); | ||||
bracket[n] = ']'; | bracket[n] = ']'; | ||||
bracket[n + 1] = '\0'; | bracket[n + 1] = '\0'; | ||||
p->end = bracket+n+1; | p->end = bracket+n+1; | ||||
p_bracket(p); | p_bracket(p); | ||||
assert(p->next == p->end); | assert(p->next == p->end); | ||||
p->next = oldnext; | p->next = oldnext; | ||||
p->end = oldend; | p->end = oldend; | ||||
} | } | ||||
/* | /* | ||||
- ordinary - emit an ordinary character | - ordinary - emit an ordinary character | ||||
== static void ordinary(struct parse *p, wint_t ch); | == static void ordinary(struct parse *p, wint_t ch); | ||||
*/ | */ | ||||
static void | static void | ||||
ordinary(struct parse *p, wint_t ch) | ordinary(struct parse *p, wint_t ch) | ||||
{ | { | ||||
cset *cs; | cset *cs; | ||||
if ((p->g->cflags®_ICASE) && iswalpha(ch) && othercase(ch) != ch) | if ((p->g->cflags®_ICASE) && iswalpha(ch) && hasothercase(ch)) | ||||
bothcases(p, ch); | bothcases(p, ch); | ||||
else if ((ch & OPDMASK) == ch) | else if ((ch & OPDMASK) == ch) | ||||
EMIT(OCHAR, ch); | EMIT(OCHAR, ch); | ||||
else { | else { | ||||
/* | /* | ||||
* Kludge: character is too big to fit into an OCHAR operand. | * Kludge: character is too big to fit into an OCHAR operand. | ||||
* Emit a singleton set. | * Emit a singleton set. | ||||
*/ | */ | ||||
▲ Show 20 Lines • Show All 822 Lines • Show Last 20 Lines |