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 int may_escape(struct parse *p, const wint_t ch); | |||||
static wint_t othercase(wint_t ch); | static wint_t othercase(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); | ||||
▲ Show 20 Lines • Show All 293 Lines • ▼ Show 20 Lines | case '\\': | ||||
switch (wc) { | switch (wc) { | ||||
case '<': | case '<': | ||||
EMIT(OBOW, 0); | EMIT(OBOW, 0); | ||||
break; | break; | ||||
case '>': | case '>': | ||||
EMIT(OEOW, 0); | EMIT(OEOW, 0); | ||||
break; | break; | ||||
default: | default: | ||||
if (may_escape(p, wc) == 0) | |||||
ordinary(p, wc); | ordinary(p, wc); | ||||
else | |||||
SETERROR(REG_EESCAPE); | |||||
break; | break; | ||||
} | } | ||||
break; | break; | ||||
default: | default: | ||||
if (p->error != 0) | if (p->error != 0) | ||||
return (false); | return (false); | ||||
p->next--; | p->next--; | ||||
wc = WGETNEXT(); | wc = WGETNEXT(); | ||||
▲ Show 20 Lines • Show All 345 Lines • ▼ Show 20 Lines | case '*': | ||||
*/ | */ | ||||
(void)REQUIRE(bc->nchain == 0, REG_BADRPT); | (void)REQUIRE(bc->nchain == 0, REG_BADRPT); | ||||
/* FALLTHROUGH */ | /* FALLTHROUGH */ | ||||
default: | default: | ||||
if (p->error != 0) | if (p->error != 0) | ||||
return (false); /* Definitely not $... */ | return (false); /* Definitely not $... */ | ||||
p->next--; | p->next--; | ||||
wc = WGETNEXT(); | wc = WGETNEXT(); | ||||
if ((c & BACKSL) == 0 || may_escape(p, wc) == 0) | |||||
ordinary(p, wc); | ordinary(p, wc); | ||||
else | |||||
SETERROR(REG_EESCAPE); | |||||
break; | break; | ||||
} | } | ||||
if (EAT('*')) { /* implemented as +? */ | if (EAT('*')) { /* implemented as +? */ | ||||
/* this case does not require the (y|) trick, noKLUDGE */ | /* this case does not require the (y|) trick, noKLUDGE */ | ||||
INSERT(OPLUS_, pos); | INSERT(OPLUS_, pos); | ||||
ASTERN(O_PLUS, pos); | ASTERN(O_PLUS, pos); | ||||
INSERT(OQUEST_, pos); | INSERT(OQUEST_, pos); | ||||
▲ Show 20 Lines • Show All 278 Lines • ▼ Show 20 Lines | p_b_coll_elem(struct parse *p, | ||||
memset(&mbs, 0, sizeof(mbs)); | memset(&mbs, 0, sizeof(mbs)); | ||||
if ((clen = mbrtowc(&wc, sp, len, &mbs)) == len) | if ((clen = mbrtowc(&wc, sp, len, &mbs)) == len) | ||||
return (wc); /* single character */ | return (wc); /* single character */ | ||||
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); | ||||
} | |||||
/* | |||||
- may_escape - determine whether 'ch' is escape-able in the current context | |||||
== static int may_escape(struct parse *p, const wint_t ch) | |||||
*/ | |||||
static int | |||||
may_escape(struct parse *p, const wint_t ch) | |||||
{ | |||||
if (isalpha(ch) || ch == '\'' || ch == '`') | |||||
return (1); | |||||
return (0); | |||||
#ifdef NOTYET | |||||
/* | |||||
* Build a whitelist of characters that may be escaped to produce an | |||||
* ordinary in the current context. This assumes that these have not | |||||
* been otherwise interpreted as a special character. Escaping an | |||||
* ordinary character yields undefined results according to | |||||
* IEEE 1003.1-2008. Some extensions (notably, some GNU extensions) take | |||||
* advantage of this and use escaped ordinary characters to provide | |||||
* special meaning, e.g. \b, \B, \w, \W, \s, \S. | |||||
*/ | |||||
switch(ch) { | |||||
case '|': | |||||
case '+': | |||||
case '?': | |||||
/* The above characters may not be escaped in BREs */ | |||||
if (!(p->g->cflags®_EXTENDED)) | |||||
return 1; | |||||
/* Fallthrough */ | |||||
case '(': | |||||
case ')': | |||||
case '{': | |||||
case '}': | |||||
case '.': | |||||
case '[': | |||||
case ']': | |||||
case '\\': | |||||
case '*': | |||||
case '^': | |||||
case '$': | |||||
return 0; | |||||
default: | |||||
return 1; | |||||
} | |||||
#endif | |||||
} | } | ||||
/* | /* | ||||
- othercase - return the case counterpart of an alphabetic | - othercase - return the case counterpart of an alphabetic | ||||
== static wint_t othercase(wint_t ch); | == static wint_t othercase(wint_t ch); | ||||
*/ | */ | ||||
static wint_t /* if no counterpart, return ch */ | static wint_t /* if no counterpart, return ch */ | ||||
othercase(wint_t ch) | othercase(wint_t ch) | ||||
▲ Show 20 Lines • Show All 879 Lines • Show Last 20 Lines |