in tools/dev/awk/b.c [764:846]
int relex(void) /* lexical analyzer for reparse */
{
int c, n;
int cflag;
static uschar *buf = 0;
static int bufsz = 100;
uschar *bp;
struct charclass *cc;
int i;
switch (c = *prestr++) {
case '|': return OR;
case '*': return STAR;
case '+': return PLUS;
case '?': return QUEST;
case '.': return DOT;
case '\0': prestr--; return '\0';
case '^':
case '$':
case '(':
case ')':
return c;
case '\\':
rlxval = quoted((char **) &prestr);
return CHAR;
default:
rlxval = c;
return CHAR;
case '[':
if (buf == 0 && (buf = (uschar *) malloc(bufsz)) == NULL)
FATAL("out of space in reg expr %.10s..", lastre);
bp = buf;
if (*prestr == '^') {
cflag = 1;
prestr++;
}
else
cflag = 0;
n = 2 * strlen((const char *) prestr)+1;
if (!adjbuf((char **) &buf, &bufsz, n, n, (char **) &bp, "relex1"))
FATAL("out of space for reg expr %.10s...", lastre);
for (; ; ) {
if ((c = *prestr++) == '\\') {
*bp++ = '\\';
if ((c = *prestr++) == '\0')
FATAL("nonterminated character class %.20s...", lastre);
*bp++ = c;
/* } else if (c == '\n') { */
/* FATAL("newline in character class %.20s...", lastre); */
} else if (c == '[' && *prestr == ':') {
/* POSIX char class names, Dag-Erling Smorgrav, des@ofug.org */
for (cc = charclasses; cc->cc_name; cc++)
if (strncmp((const char *) prestr + 1, (const char *) cc->cc_name, cc->cc_namelen) == 0)
break;
if (cc->cc_name != NULL && prestr[1 + cc->cc_namelen] == ':' &&
prestr[2 + cc->cc_namelen] == ']') {
prestr += cc->cc_namelen + 3;
for (i = 0; i < NCHARS; i++) {
if (!adjbuf((char **) &buf, &bufsz, bp-buf+1, 100, (char **) &bp, "relex2"))
FATAL("out of space for reg expr %.10s...", lastre);
if (cc->cc_func(i)) {
*bp++ = i;
n++;
}
}
} else
*bp++ = c;
} else if (c == '\0') {
FATAL("nonterminated character class %.20s", lastre);
} else if (bp == buf) { /* 1st char is special */
*bp++ = c;
} else if (c == ']') {
*bp++ = 0;
rlxstr = (uschar *) tostring((char *) buf);
if (cflag == 0)
return CCL;
else
return NCCL;
} else
*bp++ = c;
}
}
}