version 1.13, 1998/12/13 12:21:46 |
version 1.14, 1999/09/16 11:45:21 |
Line 50 __RCSID("$NetBSD$"); |
|
Line 50 __RCSID("$NetBSD$"); |
|
|
|
#include "namespace.h" |
#include "namespace.h" |
#include <sys/types.h> |
#include <sys/types.h> |
#include <stdio.h> |
|
#include <string.h> |
#include <assert.h> |
#include <ctype.h> |
#include <ctype.h> |
#include <limits.h> |
#include <limits.h> |
#include <stdlib.h> |
|
#include <regex.h> |
#include <regex.h> |
|
#include <stdio.h> |
|
#include <stdlib.h> |
|
#include <string.h> |
|
|
#ifdef __weak_alias |
#ifdef __weak_alias |
__weak_alias(regcomp,_regcomp); |
__weak_alias(regcomp,_regcomp); |
|
|
# define GOODFLAGS(f) ((f)&~REG_DUMP) |
# define GOODFLAGS(f) ((f)&~REG_DUMP) |
#endif |
#endif |
|
|
|
_DIAGASSERT(preg != NULL); |
|
_DIAGASSERT(pattern != NULL); |
|
#ifdef _DIAGNOSTIC |
|
if (preg == NULL || pattern == NULL) |
|
return (REG_INVARG); |
|
#endif |
|
|
cflags = GOODFLAGS(cflags); |
cflags = GOODFLAGS(cflags); |
if ((cflags®_EXTENDED) && (cflags®_NOSPEC)) |
if ((cflags®_EXTENDED) && (cflags®_NOSPEC)) |
return(REG_INVARG); |
return(REG_INVARG); |
Line 305 int stop; /* character this ERE should |
|
Line 314 int stop; /* character this ERE should |
|
sopno conc; |
sopno conc; |
int first = 1; /* is this the first alternative? */ |
int first = 1; /* is this the first alternative? */ |
|
|
|
_DIAGASSERT(p != NULL); |
|
|
for (;;) { |
for (;;) { |
/* do a bunch of concatenated expressions */ |
/* do a bunch of concatenated expressions */ |
conc = HERE(); |
conc = HERE(); |
Line 351 struct parse *p; |
|
Line 362 struct parse *p; |
|
sopno subno; |
sopno subno; |
int wascaret = 0; |
int wascaret = 0; |
|
|
|
_DIAGASSERT(p != NULL); |
|
|
assert(MORE()); /* caller should have ensured this */ |
assert(MORE()); /* caller should have ensured this */ |
c = GETNEXT(); |
c = GETNEXT(); |
|
|
|
|
p_str(p) |
p_str(p) |
struct parse *p; |
struct parse *p; |
{ |
{ |
|
|
|
_DIAGASSERT(p != NULL); |
|
|
REQUIRE(MORE(), REG_EMPTY); |
REQUIRE(MORE(), REG_EMPTY); |
while (MORE()) |
while (MORE()) |
ordinary(p, GETNEXT()); |
ordinary(p, GETNEXT()); |
Line 516 struct parse *p; |
|
Line 532 struct parse *p; |
|
int end1; /* first terminating character */ |
int end1; /* first terminating character */ |
int end2; /* second terminating character */ |
int end2; /* second terminating character */ |
{ |
{ |
sopno start = HERE(); |
sopno start; |
int first = 1; /* first subexpression? */ |
int first = 1; /* first subexpression? */ |
int wasdollar = 0; |
int wasdollar = 0; |
|
|
|
_DIAGASSERT(p != NULL); |
|
|
|
start = HERE(); |
|
|
if (EAT('^')) { |
if (EAT('^')) { |
EMIT(OBOL, 0); |
EMIT(OBOL, 0); |
p->g->iflags |= USEBOL; |
p->g->iflags |= USEBOL; |
Line 556 int starordinary; /* is a leading * an |
|
Line 576 int starordinary; /* is a leading * an |
|
sopno subno; |
sopno subno; |
# define BACKSL (1<<CHAR_BIT) |
# define BACKSL (1<<CHAR_BIT) |
|
|
|
_DIAGASSERT(p != NULL); |
|
|
pos = HERE(); /* repetion op, if any, covers from here */ |
pos = HERE(); /* repetion op, if any, covers from here */ |
|
|
assert(MORE()); /* caller should have ensured this */ |
assert(MORE()); /* caller should have ensured this */ |
Line 668 struct parse *p; |
|
Line 690 struct parse *p; |
|
int count = 0; |
int count = 0; |
int ndigits = 0; |
int ndigits = 0; |
|
|
|
_DIAGASSERT(p != NULL); |
|
|
while (MORE() && isdigit(PEEK()) && count <= DUPMAX) { |
while (MORE() && isdigit(PEEK()) && count <= DUPMAX) { |
count = count*10 + (GETNEXT() - '0'); |
count = count*10 + (GETNEXT() - '0'); |
ndigits++; |
ndigits++; |
|
|
p_bracket(p) |
p_bracket(p) |
struct parse *p; |
struct parse *p; |
{ |
{ |
cset *cs = allocset(p); |
cset *cs; |
int invert = 0; |
int invert = 0; |
|
|
|
_DIAGASSERT(p != NULL); |
|
|
|
cs = allocset(p); |
|
|
/* Dept of Truly Sickening Special-Case Kludges */ |
/* Dept of Truly Sickening Special-Case Kludges */ |
if (p->next + 5 < p->end && strncmp(p->next, "[:<:]]", |
if (p->next + 5 < p->end && strncmp(p->next, "[:<:]]", |
(size_t)6) == 0) { |
(size_t)6) == 0) { |
|
|
char start, finish; |
char start, finish; |
int i; |
int i; |
|
|
|
_DIAGASSERT(p != NULL); |
|
_DIAGASSERT(cs != NULL); |
|
|
/* classify what we've got */ |
/* classify what we've got */ |
switch ((MORE()) ? PEEK() : '\0') { |
switch ((MORE()) ? PEEK() : '\0') { |
case '[': |
case '[': |
Line 832 p_b_cclass(p, cs) |
|
Line 863 p_b_cclass(p, cs) |
|
struct parse *p; |
struct parse *p; |
cset *cs; |
cset *cs; |
{ |
{ |
char *sp = p->next; |
char *sp; |
const struct cclass *cp; |
const struct cclass *cp; |
size_t len; |
size_t len; |
const char *u; |
const char *u; |
char c; |
char c; |
|
|
|
_DIAGASSERT(p != NULL); |
|
_DIAGASSERT(cs != NULL); |
|
|
|
sp = p->next; |
|
|
while (MORE() && isalpha(PEEK())) |
while (MORE() && isalpha(PEEK())) |
NEXT(); |
NEXT(); |
len = p->next - sp; |
len = p->next - sp; |
|
|
{ |
{ |
char c; |
char c; |
|
|
|
_DIAGASSERT(p != NULL); |
|
_DIAGASSERT(cs != NULL); |
|
|
c = p_b_coll_elem(p, '='); |
c = p_b_coll_elem(p, '='); |
CHadd(cs, c); |
CHadd(cs, c); |
} |
} |
Line 884 struct parse *p; |
|
Line 923 struct parse *p; |
|
{ |
{ |
char value; |
char value; |
|
|
|
_DIAGASSERT(p != NULL); |
|
|
REQUIRE(MORE(), REG_EBRACK); |
REQUIRE(MORE(), REG_EBRACK); |
if (!EATTWO('[', '.')) |
if (!EATTWO('[', '.')) |
return(GETNEXT()); |
return(GETNEXT()); |
Line 903 p_b_coll_elem(p, endc) |
|
Line 944 p_b_coll_elem(p, endc) |
|
struct parse *p; |
struct parse *p; |
int endc; /* name ended by endc,']' */ |
int endc; /* name ended by endc,']' */ |
{ |
{ |
char *sp = p->next; |
char *sp; |
const struct cname *cp; |
const struct cname *cp; |
size_t len; |
size_t len; |
|
|
|
_DIAGASSERT(p != NULL); |
|
|
|
sp = p->next; |
|
|
while (MORE() && !SEETWO(endc, ']')) |
while (MORE() && !SEETWO(endc, ']')) |
NEXT(); |
NEXT(); |
if (!MORE()) { |
if (!MORE()) { |
Line 951 bothcases(p, ch) |
|
Line 996 bothcases(p, ch) |
|
struct parse *p; |
struct parse *p; |
int ch; |
int ch; |
{ |
{ |
char *oldnext = p->next; |
char *oldnext; |
char *oldend = p->end; |
char *oldend; |
char bracket[3]; |
char bracket[3]; |
|
|
|
_DIAGASSERT(p != NULL); |
|
|
|
oldnext = p->next; |
|
oldend = p->end; |
|
|
assert(othercase(ch) != ch); /* p_bracket() would recurse */ |
assert(othercase(ch) != ch); /* p_bracket() would recurse */ |
p->next = bracket; |
p->next = bracket; |
p->end = bracket+2; |
p->end = bracket+2; |
|
Line 1026 ordinary(p, ch) |
|
struct parse *p; |
struct parse *p; |
int ch; |
int ch; |
{ |
{ |
cat_t *cap = p->g->categories; |
cat_t *cap; |
|
|
|
_DIAGASSERT(p != NULL); |
|
|
|
cap = p->g->categories; |
if ((p->g->cflags®_ICASE) && isalpha(ch) && othercase(ch) != ch) |
if ((p->g->cflags®_ICASE) && isalpha(ch) && othercase(ch) != ch) |
bothcases(p, ch); |
bothcases(p, ch); |
else { |
else { |
|
|
nonnewline(p) |
nonnewline(p) |
struct parse *p; |
struct parse *p; |
{ |
{ |
char *oldnext = p->next; |
char *oldnext; |
char *oldend = p->end; |
char *oldend; |
char bracket[4]; |
char bracket[4]; |
|
|
|
_DIAGASSERT(p != NULL); |
|
|
|
oldnext = p->next; |
|
oldend = p->end; |
|
|
p->next = bracket; |
p->next = bracket; |
p->end = bracket+3; |
p->end = bracket+3; |
bracket[0] = '^'; |
bracket[0] = '^'; |
Line 1024 sopno start; /* operand from here to e |
|
Line 1082 sopno start; /* operand from here to e |
|
int from; /* repeated from this number */ |
int from; /* repeated from this number */ |
int to; /* to this number of times (maybe INFINITY) */ |
int to; /* to this number of times (maybe INFINITY) */ |
{ |
{ |
sopno finish = HERE(); |
sopno finish; |
# define N 2 |
# define N 2 |
# define INF 3 |
# define INF 3 |
# define REP(f, t) ((f)*8 + (t)) |
# define REP(f, t) ((f)*8 + (t)) |
# define MAP(n) (((n) <= 1) ? (n) : ((n) == INFINITY) ? INF : N) |
# define MAP(n) (((n) <= 1) ? (n) : ((n) == INFINITY) ? INF : N) |
sopno copy; |
sopno copy; |
|
|
|
_DIAGASSERT(p != NULL); |
|
|
|
finish = HERE(); |
|
|
if (p->error != 0) /* head off possible runaway recursion */ |
if (p->error != 0) /* head off possible runaway recursion */ |
return; |
return; |
|
|
|
|
struct parse *p; |
struct parse *p; |
int e; |
int e; |
{ |
{ |
|
|
|
_DIAGASSERT(p != NULL); |
|
|
if (p->error == 0) /* keep earliest error condition */ |
if (p->error == 0) /* keep earliest error condition */ |
p->error = e; |
p->error = e; |
p->next = nuls; /* try to bring things to a halt */ |
p->next = nuls; /* try to bring things to a halt */ |
|
|
allocset(p) |
allocset(p) |
struct parse *p; |
struct parse *p; |
{ |
{ |
int no = p->g->ncsets++; |
int no; |
size_t nc; |
size_t nc; |
size_t nbytes; |
size_t nbytes; |
cset *cs; |
cset *cs; |
size_t css = (size_t)p->g->csetsize; |
size_t css; |
int i; |
int i; |
|
|
|
_DIAGASSERT(p != NULL); |
|
|
|
no = p->g->ncsets++; |
|
css = (size_t)p->g->csetsize; |
if (no >= p->ncsalloc) { /* need another column of space */ |
if (no >= p->ncsalloc) { /* need another column of space */ |
p->ncsalloc += CHAR_BIT; |
p->ncsalloc += CHAR_BIT; |
nc = p->ncsalloc; |
nc = p->ncsalloc; |
Line 1164 struct parse *p; |
|
Line 1233 struct parse *p; |
|
cset *cs; |
cset *cs; |
{ |
{ |
int i; |
int i; |
cset *top = &p->g->sets[p->g->ncsets]; |
cset *top; |
size_t css = (size_t)p->g->csetsize; |
size_t css; |
|
|
|
_DIAGASSERT(p != NULL); |
|
_DIAGASSERT(cs != NULL); |
|
|
|
top = &p->g->sets[p->g->ncsets]; |
|
css = (size_t)p->g->csetsize; |
|
|
for (i = 0; i < css; i++) |
for (i = 0; i < css; i++) |
CHsub(cs, i); |
CHsub(cs, i); |
Line 1188 freezeset(p, cs) |
|
Line 1263 freezeset(p, cs) |
|
struct parse *p; |
struct parse *p; |
cset *cs; |
cset *cs; |
{ |
{ |
uch h = cs->hash; |
uch h; |
int i; |
int i; |
cset *top = &p->g->sets[p->g->ncsets]; |
cset *top; |
cset *cs2; |
cset *cs2; |
size_t css = (size_t)p->g->csetsize; |
size_t css; |
|
|
|
_DIAGASSERT(p != NULL); |
|
_DIAGASSERT(cs != NULL); |
|
|
|
h = cs->hash; |
|
top = &p->g->sets[p->g->ncsets]; |
|
css = (size_t)p->g->csetsize; |
|
|
/* look for an earlier one which is the same */ |
/* look for an earlier one which is the same */ |
for (cs2 = &p->g->sets[0]; cs2 < top; cs2++) |
for (cs2 = &p->g->sets[0]; cs2 < top; cs2++) |
Line 1223 struct parse *p; |
|
Line 1305 struct parse *p; |
|
cset *cs; |
cset *cs; |
{ |
{ |
int i; |
int i; |
size_t css = (size_t)p->g->csetsize; |
size_t css; |
|
|
|
_DIAGASSERT(p != NULL); |
|
_DIAGASSERT(cs != NULL); |
|
|
|
css = (size_t)p->g->csetsize; |
|
|
for (i = 0; i < css; i++) |
for (i = 0; i < css; i++) |
if (CHIN(cs, i)) |
if (CHIN(cs, i)) |
Line 1242 struct parse *p; |
|
Line 1329 struct parse *p; |
|
cset *cs; |
cset *cs; |
{ |
{ |
int i; |
int i; |
size_t css = (size_t)p->g->csetsize; |
size_t css; |
int n = 0; |
int n = 0; |
|
|
|
_DIAGASSERT(p != NULL); |
|
_DIAGASSERT(cs != NULL); |
|
|
|
css = (size_t)p->g->csetsize; |
|
|
for (i = 0; i < css; i++) |
for (i = 0; i < css; i++) |
if (CHIN(cs, i)) |
if (CHIN(cs, i)) |
n++; |
n++; |
Line 1262 struct parse *p; |
|
Line 1354 struct parse *p; |
|
cset *cs; |
cset *cs; |
const char *cp; |
const char *cp; |
{ |
{ |
size_t oldend = cs->smultis; |
size_t oldend; |
|
|
|
_DIAGASSERT(p != NULL); |
|
_DIAGASSERT(cs != NULL); |
|
_DIAGASSERT(cp != NULL); |
|
|
|
oldend = cs->smultis; |
|
|
cs->smultis += strlen(cp) + 1; |
cs->smultis += strlen(cp) + 1; |
if (cs->multis == NULL) |
if (cs->multis == NULL) |
|
|
cset *cs; |
cset *cs; |
char *cp; |
char *cp; |
{ |
{ |
char *fp = mcfind(cs, cp); |
char *fp; |
size_t len = strlen(fp); |
size_t len; |
|
|
|
_DIAGASSERT(cs != NULL); |
|
_DIAGASSERT(cp != NULL); |
|
|
|
fp = mcfind(cs, cp); |
|
len = strlen(fp); |
|
|
assert(fp != NULL); |
assert(fp != NULL); |
(void) memmove(fp, fp + len + 1, |
(void) memmove(fp, fp + len + 1, |
|
|
cset *cs; |
cset *cs; |
char *cp; |
char *cp; |
{ |
{ |
|
|
|
_DIAGASSERT(cs != NULL); |
|
_DIAGASSERT(cp != NULL); |
|
|
return(mcfind(cs, cp) != NULL); |
return(mcfind(cs, cp) != NULL); |
} |
} |
|
|
|
|
{ |
{ |
char *p; |
char *p; |
|
|
|
_DIAGASSERT(cs != NULL); |
|
_DIAGASSERT(cp != NULL); |
|
|
if (cs->multis == NULL) |
if (cs->multis == NULL) |
return(NULL); |
return(NULL); |
for (p = cs->multis; *p != '\0'; p += strlen(p) + 1) |
for (p = cs->multis; *p != '\0'; p += strlen(p) + 1) |
Line 1351 mcinvert(p, cs) |
|
Line 1462 mcinvert(p, cs) |
|
struct parse *p; |
struct parse *p; |
cset *cs; |
cset *cs; |
{ |
{ |
|
|
|
_DIAGASSERT(p != NULL); |
|
_DIAGASSERT(cs != NULL); |
|
|
assert(cs->multis == NULL); /* xxx */ |
assert(cs->multis == NULL); /* xxx */ |
} |
} |
|
|
|
|
struct parse *p; |
struct parse *p; |
cset *cs; |
cset *cs; |
{ |
{ |
|
|
|
_DIAGASSERT(p != NULL); |
|
_DIAGASSERT(cs != NULL); |
|
|
assert(cs->multis == NULL); /* xxx */ |
assert(cs->multis == NULL); /* xxx */ |
} |
} |
|
|
|
|
{ |
{ |
uch *col; |
uch *col; |
int i; |
int i; |
int ncols = (g->ncsets+(CHAR_BIT-1)) / CHAR_BIT; |
int ncols; |
unsigned uc = (unsigned char)c; |
unsigned uc = (unsigned char)c; |
|
|
|
_DIAGASSERT(g != NULL); |
|
|
|
ncols = (g->ncsets+(CHAR_BIT-1)) / CHAR_BIT; |
|
|
for (i = 0, col = g->setbits; i < ncols; i++, col += g->csetsize) |
for (i = 0, col = g->setbits; i < ncols; i++, col += g->csetsize) |
if (col[uc] != 0) |
if (col[uc] != 0) |
return(1); |
return(1); |
|
|
{ |
{ |
uch *col; |
uch *col; |
int i; |
int i; |
int ncols = (g->ncsets+(CHAR_BIT-1)) / CHAR_BIT; |
int ncols; |
unsigned uc1 = (unsigned char)c1; |
unsigned uc1 = (unsigned char)c1; |
unsigned uc2 = (unsigned char)c2; |
unsigned uc2 = (unsigned char)c2; |
|
|
|
_DIAGASSERT(g != NULL); |
|
|
|
ncols = (g->ncsets+(CHAR_BIT-1)) / CHAR_BIT; |
|
|
for (i = 0, col = g->setbits; i < ncols; i++, col += g->csetsize) |
for (i = 0, col = g->setbits; i < ncols; i++, col += g->csetsize) |
if (col[uc1] != col[uc2]) |
if (col[uc1] != col[uc2]) |
return(0); |
return(0); |
Line 1421 categorize(p, g) |
|
Line 1548 categorize(p, g) |
|
struct parse *p; |
struct parse *p; |
struct re_guts *g; |
struct re_guts *g; |
{ |
{ |
cat_t *cats = g->categories; |
cat_t *cats; |
int c; |
int c; |
int c2; |
int c2; |
cat_t cat; |
cat_t cat; |
|
|
|
_DIAGASSERT(p != NULL); |
|
_DIAGASSERT(g != NULL); |
|
|
|
cats = g->categories; |
|
|
/* avoid making error situations worse */ |
/* avoid making error situations worse */ |
if (p->error != 0) |
if (p->error != 0) |
return; |
return; |
Line 1450 struct parse *p; |
|
Line 1582 struct parse *p; |
|
sopno start; /* from here */ |
sopno start; /* from here */ |
sopno finish; /* to this less one */ |
sopno finish; /* to this less one */ |
{ |
{ |
sopno ret = HERE(); |
sopno ret; |
sopno len = finish - start; |
sopno len = finish - start; |
|
|
|
_DIAGASSERT(p != NULL); |
|
|
|
ret = HERE(); |
|
|
assert(finish >= start); |
assert(finish >= start); |
if (len == 0) |
if (len == 0) |
return(ret); |
return(ret); |
Line 1478 struct parse *p; |
|
Line 1614 struct parse *p; |
|
sop op; |
sop op; |
sopno opnd; |
sopno opnd; |
{ |
{ |
|
|
|
_DIAGASSERT(p != NULL); |
|
|
/* avoid making error situations worse */ |
/* avoid making error situations worse */ |
if (p->error != 0) |
if (p->error != 0) |
return; |
return; |
|
|
sop s; |
sop s; |
int i; |
int i; |
|
|
|
_DIAGASSERT(p != NULL); |
|
|
/* avoid making error situations worse */ |
/* avoid making error situations worse */ |
if (p->error != 0) |
if (p->error != 0) |
return; |
return; |
Line 1543 struct parse *p; |
|
Line 1684 struct parse *p; |
|
sopno pos; |
sopno pos; |
sopno value; |
sopno value; |
{ |
{ |
|
|
|
_DIAGASSERT(p != NULL); |
|
|
/* avoid making error situations worse */ |
/* avoid making error situations worse */ |
if (p->error != 0) |
if (p->error != 0) |
return; |
return; |
|
|
{ |
{ |
sop *sp; |
sop *sp; |
|
|
|
_DIAGASSERT(p != NULL); |
|
|
if (p->ssize >= size) |
if (p->ssize >= size) |
return; |
return; |
|
|
Line 1583 stripsnug(p, g) |
|
Line 1729 stripsnug(p, g) |
|
struct parse *p; |
struct parse *p; |
struct re_guts *g; |
struct re_guts *g; |
{ |
{ |
|
|
|
_DIAGASSERT(p != NULL); |
|
_DIAGASSERT(g != NULL); |
|
|
g->nstates = p->slen; |
g->nstates = p->slen; |
g->strip = realloc(p->strip, p->slen * sizeof(sop)); |
g->strip = realloc(p->strip, p->slen * sizeof(sop)); |
if (g->strip == NULL) { |
if (g->strip == NULL) { |
Line 1614 struct re_guts *g; |
|
Line 1764 struct re_guts *g; |
|
char *cp; |
char *cp; |
sopno i; |
sopno i; |
|
|
|
_DIAGASSERT(p != NULL); |
|
_DIAGASSERT(g != NULL); |
|
|
/* avoid making error situations worse */ |
/* avoid making error situations worse */ |
if (p->error != 0) |
if (p->error != 0) |
return; |
return; |
Line 1692 struct re_guts *g; |
|
Line 1845 struct re_guts *g; |
|
sopno plusnest = 0; |
sopno plusnest = 0; |
sopno maxnest = 0; |
sopno maxnest = 0; |
|
|
|
_DIAGASSERT(p != NULL); |
|
_DIAGASSERT(g != NULL); |
|
|
if (p->error != 0) |
if (p->error != 0) |
return(0); /* there may not be an OEND */ |
return(0); /* there may not be an OEND */ |
|
|