30 #define BOL '^' // start-of-line anchor
31 #define EOL '$' // end-of-line anchor
32 #define ANY '.' // matches any character
33 #define CCL '[' // start a character class
34 #define CCLEND ']' // end a character class
35 #define NCCL '^' // negates character class if 1st character
36 #define CLOSURE '*' // Kleene closure (matches 0 or more)
37 #define PCLOSE '+' // Positive closure (1 or more)
38 #define OPT '?' // Optional closure (0 or 1)
54 #define ISHEXDIGIT(x) isxdigit((unsigned char)x)
56 #define ISHEXDIGIT(x) (isdigit(x) \
57 || ('a'<=(x) && (x)<='f') \
58 || ('A'<=(x) && (x)<='F') )
61 #define ISOCTDIGIT(x) ('0'<=(x) && (x)<='7')
64 #define MAPSIZE 16 // need this many Pattern_t elements for
85 #ifdef SETBIT // from Rtypes.h
91 map[b >> 4] |= 1 << (b & 0x0f);
98 return map[b >> 4] & (1 << (b & 0x0f));
103 #define E_NONE 0 // Possible return values from pat_err
104 #define E_ILLEGAL 1 // Set in Makepat() to indicate prob-
105 #define E_NOMEM 2 // lems that came up while making the
106 #define E_PAT 3 // pattern template.
113 static int omatch(
const char**,
size_t*,
const Pattern_t*,
const char*);
114 static const char*
patcmp(
const char*,
size_t,
const Pattern_t*,
const char*);
115 static int esc(
const char**);
151 if (cur >= &pat[maxpat - 1])
goto exit;
173 if (((cur - pat) +
MAPSIZE) >= maxpat)
177 exp =
doccl(cur, exp);
178 if (*exp !=
CCLEND)
goto exit;
195 memmove( prev+1, prev, (cur-prev)*
sizeof(*cur));
223 const char** startpat)
226 const char* endp = 0;
229 endp =
patcmp(str, slen, pat+1, str);
232 const char* start = str;
233 while ((endp =
patcmp(str, slen, pat, start)) == 0 && slen != 0)
249 negative = (*src ==
NCCL);
252 memset(map, 0,
MAPSIZE*
sizeof(*map));
254 while (*src && *src !=
CCLEND) {
255 int isCCL = (*src ==
CCL);
256 unsigned char first =
esc(&src);
258 if (isCCL && *src && *src ==
CCLEND) {
262 if (*src ==
'-' && src[1] && src[1] !=
CCLEND) {
264 unsigned char last =
esc(&src);
265 if (first <= last)
while (first < last )
SETBIT(++first, map);
266 else while (last < first)
SETBIT(last++, map);
271 for (
int i =
MAPSIZE; --i >= 0;)
287 static const char *
patcmp(
const char* str,
301 omatch(&str, &slen, ++pat, start);
310 if (!
omatch(&str, &slen, pat, start))
317 if (!
omatch(&str, &slen, pat, start))
322 const char* bocl = str;
323 while (slen &&
omatch(&str, &slen, pat, start))
339 while ((end =
patcmp(str, slen, pat, start)) == 0) {
341 if (str < bocl)
break;
376 case kBOL:
return (*strp == start);
379 case kEOL:
return (*slenp == 0);
383 case kANY:
if (**strp ==
'\n')
return 0;
387 case kCCL:
if (*slenp == 0 || !
TSTBIT(**strp, pat + 1))
return 0;
391 default:
if (*slenp == 0 || (
unsigned char) **strp != *pat)
return 0;
408 return (isdigit(c) ? (c)-
'0': ((toupper((
unsigned char)c))-
'A')+10) & 0xf;
417 return ( ((c)-
'0') & 0x7 );
438 static int esc(
const char** s)
446 switch (toupper((
unsigned char)**s)) {
447 case '\0': rval =
'\\';
break;
448 case 'B': rval =
'\b';
break;
449 case 'F': rval =
'\f';
break;
450 case 'N': rval =
'\n';
break;
451 case 'R': rval =
'\r';
break;
452 case 'S': rval =
' ';
break;
453 case 'T': rval =
'\t';
break;
454 case 'E': rval =
'\033';
break;
458 rval = toupper((
unsigned char)rval) -
'@';
465 rval =
hex2bin((
unsigned char) *(*s)++);
469 rval |=
hex2bin((
unsigned char) *(*s)++);
493 return (
unsigned char)rval;
const char * Matchs(const char *str, size_t slen, const Pattern_t *pat, const char **startpat)
Match a string with a pattern.
static int omatch(const char **, size_t *, const Pattern_t *, const char *)
Match one pattern element, pointed at by pat, against the character at **strp.
static const char * patcmp(const char *, size_t, const Pattern_t *, const char *)
Like strcmp, but compares str against pat.
static int hex2bin(int)
Convert the hex digit represented by 'c' to an int.
static void SETBIT(unsigned char b, Pattern_t *map)
static const char * doccl(Pattern_t *, const char *)
Set bits in the map corresponding to characters specified in the src character class.
static int TSTBIT(unsigned char b, const Pattern_t *map)
void ADVANCE(const Pattern_t *&pat)
Advance a pointer into the pattern template to the next pattern element, this is a+1 for all pattern ...
static int oct2bin(int)
Convert the hex digit represented by 'c' to an int.
int Makepat(const char *exp, Pattern_t *pat, int maxpat)
Make a pattern template from the string pointed to by exp.
static int esc(const char **)
Map escape sequences into their equivalent symbols.