/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2005 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
/* All Rights Reserved */
#pragma ident "%Z%%M% %I% %E% SMI"
#define DEBUG
#include "awk.h"
#include "y.tab.h"
/* NCHARS is 2**n */
/*
* encoding in tree Nodes:
* leaf (CCL, NCCL, CHAR, DOT, FINAL, ALL):
* left is index, right contains value or pointer to value
* unary (STAR, PLUS, QUEST): left is child, right is null
* binary (CAT, OR): left and right are children
* parent contains pointer to parent
*/
int rlxval;
static int setcnt;
static int poscnt;
int patlen;
static void overflo(char *);
static int relex(void);
fa *
{
if (compile_time) /* a constant for sure */
for (i = 0; i < nfatab; i++) { /* is it there already? */
return (fatab[i]);
}
}
nfatab++;
return (pfa);
}
nuse = 0;
for (i = 1; i < nfatab; i++)
nuse = i;
}
return (pfa);
}
fa *
/* anchor = 1 for anchored matches, else 0 */
{
fa *f;
p = reparse(s);
/* put ALL STAR in front of reg. exp. */
/* put FINAL after reg. exp. */
poscnt = 0;
overflo("no room for fa");
/* penter has computed number of positions in re */
if ((f->posns[0] =
overflo("out of space in makedfa");
}
overflo("out of space in makedfa");
*f->posns[1] = 0;
return (f);
}
static int
{
register int i, k;
f->curstat = 2;
f->out[2] = 0;
f->reset = 0;
overflo("out of space in makeinit");
for (i = 0; i <= k; i++) {
}
for (i = 0; i < NCHARS; i++)
f->gototab[2][i] = 0;
if (anchor) {
for (i = 0; i < k; i++) {
}
if (f->curstat != 2)
}
return (f->curstat);
}
void
{
switch (type(p)) {
break;
break;
case CAT:
case OR:
break;
default:
break;
}
}
static void
{
switch (type(p)) {
xfree(p);
break;
xfree(p);
break;
case CAT:
case OR:
xfree(p);
break;
default:
break;
}
}
uchar *
{
register int i, c;
op = p;
i = 0;
while ((c = *p++) != 0) {
if (c == '\\') {
if ((c = *p++) == 't')
c = '\t';
else if (c == 'n')
c = '\n';
else if (c == 'f')
c = '\f';
else if (c == 'r')
c = '\r';
else if (c == 'b')
c = '\b';
else if (c == '\\')
c = '\\';
else if (isdigit(c)) {
int n = c - '0';
if (isdigit(*p)) {
n = 8 * n + *p++ - '0';
if (isdigit(*p))
n = 8 * n + *p++ - '0';
}
c = n;
} /* else */
/* c = c; */
if (*p != 0) {
c = chars[i-1];
while ((uchar)c < *p) { /* fails if *p is \\ */
chars[i++] = ++c;
}
p++;
continue;
}
}
chars[i++] = c;
}
chars[i++] = '\0';
return (ret);
}
static void
overflo(char *s)
{
}
/* enter follow set of each leaf of vertex v into lfollow[leaf] */
static void
{
register int i;
register int *p;
switch (type(v)) {
for (i = 0; i <= f->accept; i++)
setvec[i] = 0;
setcnt = 0;
follow(v); /* computes setvec and setcnt */
overflo("follow set overflow");
*p = setcnt;
for (i = f->accept; i >= 0; i--) {
if (setvec[i] == 1)
*++p = i;
}
break;
break;
case CAT:
case OR:
break;
default:
}
}
/*
* collects initially active leaves of p into setvec
* returns 0 or 1 depending on whether p matches empty string
*/
static int
{
register int b;
switch (type(p)) {
setcnt++;
}
return (0); /* empty CCL */
else
return (1);
case PLUS:
return (0);
return (1);
case STAR:
case QUEST:
return (0);
case CAT:
return (0);
return (1);
case OR:
return (0);
return (1);
}
return (-1);
}
/* collects leaves that can follow v into setvec */
static void
{
Node *p;
return;
p = parent(v);
switch (type(p)) {
case STAR:
case PLUS:
(void) first(v);
follow(p);
return;
case OR:
case QUEST:
follow(p);
return;
case CAT:
if (v == left(p)) { /* v is left child of p */
follow(p);
return;
}
} else /* v is right child */
follow(p);
return;
default:
break;
}
}
static int
{
while (*s)
if (c == *s++)
return (1);
return (0);
}
int
{
register int s, ns;
if (f->out[s])
return (1);
do {
s = ns;
else
s = cgoto(f, s, *p);
if (f->out[s])
return (1);
} while (*p++ != 0);
return (0);
}
int
{
register int s, ns;
register uchar *q;
int i, k;
if (f->reset) {
} else {
s = f->initstat;
}
patbeg = p;
patlen = -1;
do {
q = p;
do {
if (f->out[s]) /* final state */
patlen = q-p;
s = ns;
else
s = cgoto(f, s, *q);
if (s == 1) { /* no transition */
if (patlen >= 0) {
patbeg = p;
return (1);
} else
goto nextin; /* no match */
}
} while (*q++ != 0);
if (f->out[s])
if (patlen >= 0) {
patbeg = p;
return (1);
}
s = 2;
if (f->reset) {
for (i = 2; i <= f->curstat; i++)
k = *f->posns[0];
if ((f->posns[2] =
overflo("out of space in pmatch");
}
for (i = 0; i <= k; i++)
for (i = 0; i < NCHARS; i++)
f->gototab[2][i] = 0;
}
} while (*p++ != 0);
return (0);
}
int
{
register int s, ns;
register uchar *q;
int i, k;
if (f->reset) {
} else {
s = f->initstat;
}
patlen = -1;
while (*p) {
q = p;
do {
if (f->out[s]) /* final state */
patlen = q-p;
s = ns;
else
s = cgoto(f, s, *q);
if (s == 1) { /* no transition */
if (patlen > 0) {
patbeg = p;
return (1);
} else
goto nnextin; /* no nonempty match */
}
} while (*q++ != 0);
if (f->out[s])
if (patlen > 0) {
patbeg = p;
return (1);
}
s = 2;
if (f->reset) {
for (i = 2; i <= f->curstat; i++)
k = *f->posns[0];
if ((f->posns[2] =
overflo("out of state space");
}
for (i = 0; i <= k; i++)
for (i = 0; i < NCHARS; i++)
f->gototab[2][i] = 0;
}
p++;
}
return (0);
}
static Node *
{
/* parses regular expression pointed to by p */
/* uses relex() to scan regular expression */
dprintf(("reparse <%s>\n", p));
if (rtok == '\0')
if (rtok == '\0') {
return (np);
} else {
ERROR "syntax error in regular expression %s at %s",
}
/*NOTREACHED*/
return (NULL);
}
static Node *
regexp(void)
{
}
static Node *
primary(void)
{
switch (rtok) {
case CHAR:
case ALL:
case DOT:
case CCL:
/*LINTED align*/
case NCCL:
/*LINTED align*/
case '^':
case '$':
case '(':
/*LINTED align*/
}
if (rtok == ')') {
} else {
ERROR "syntax error in regular expression %s at %s",
}
default:
ERROR "illegal primary in regular expression %s at %s",
}
/*NOTREACHED*/
return (NULL);
}
static Node *
{
switch (rtok) {
default:
return (np);
}
}
static Node *
{
}
return (np);
}
static Node *
{
switch (rtok) {
case STAR:
case PLUS:
case QUEST:
default:
return (np);
}
}
static int
{
register int c;
switch (c = *prestr++) {
case '|': return OR;
case '*': return STAR;
case '+': return PLUS;
case '?': return QUEST;
case '.': return DOT;
case '^':
case '$':
case '(':
case ')':
return (c);
case '\\':
if ((c = *prestr++) == 't')
c = '\t';
else if (c == 'n')
c = '\n';
else if (c == 'f')
c = '\f';
else if (c == 'r')
c = '\r';
else if (c == 'b')
c = '\b';
else if (c == '\\')
c = '\\';
else if (isdigit(c)) {
int n = c - '0';
}
c = n;
} /* else it's now in c */
rlxval = c;
return (CHAR);
default:
rlxval = c;
return (CHAR);
case '[':
clen = 0;
if (*prestr == '^') {
cflag = 1;
prestr++;
} else
cflag = 0;
for (;;) {
if ((c = *prestr++) == '\\') {
if ((c = *prestr++) == '\0') {
}
} else if (c == ']') {
if (cflag == 0)
return (CCL);
else
return (NCCL);
} else if (c == '\n') {
ERROR "newline in character class %s...",
} else if (c == '\0') {
ERROR "nonterminated character class %s",
} else
}
/*NOTREACHED*/
}
return (0);
}
static int
{
register int i, j, k;
register int *p, *q;
for (i = 0; i <= f->accept; i++)
setvec[i] = 0;
setcnt = 0;
/* compute positions of gototab[s,c] into setvec */
p = f->posns[s];
for (i = 1; i <= *p; i++) {
k == ALL && c != 0 ||
k == CCL &&
k == NCCL &&
c != 0 && c != HAT) {
for (j = 1; j <= *q; j++) {
if (setvec[q[j]] == 0) {
setcnt++;
setvec[q[j]] = 1;
}
}
}
}
}
/* determine if setvec is a previous state */
j = 1;
for (i = f->accept; i >= 0; i--)
if (setvec[i]) {
tmpset[j++] = i;
}
/* tmpset == previous state? */
for (i = 1; i <= f->curstat; i++) {
p = f->posns[i];
if ((k = tmpset[0]) != p[0])
goto different;
for (j = 1; j <= k; j++)
if (tmpset[j] != p[j])
goto different;
/* setvec is state i */
f->gototab[s][c] = i;
return (i);
}
/* add tmpset to current set of states */
f->curstat = 2;
f->reset = 1;
for (i = 2; i < NSTATES; i++)
} else
++(f->curstat);
for (i = 0; i < NCHARS; i++)
overflo("out of space in cgoto");
for (i = 0; i <= setcnt; i++)
p[i] = tmpset[i];
else
return (f->curstat);
}
static void
{
register int i;
if (f == NULL)
return;
for (i = 0; i <= f->curstat; i++)
for (i = 0; i <= f->accept; i++)
xfree(f);
}