16884d44aSbostic /*-
2*84651319Sbostic * Copyright (c) 1991, 1993
3*84651319Sbostic * The Regents of the University of California. All rights reserved.
46884d44aSbostic *
5d84495efSbostic * %sccs.include.proprietary.c%
66884d44aSbostic */
76884d44aSbostic
84c0d4567Sbill /* Yacc productions for "expr" command: */
96b31aa05Sbostic %{
106b31aa05Sbostic typedef char *yystype;
116b31aa05Sbostic #define YYSTYPE yystype
126b31aa05Sbostic %}
134c0d4567Sbill
144c0d4567Sbill %token OR AND ADD SUBT MULT DIV REM EQ GT GEQ LT LEQ NEQ
154c0d4567Sbill %token A_STRING SUBSTR LENGTH INDEX NOARG MATCH
164c0d4567Sbill
174c0d4567Sbill /* operators listed below in increasing precedence: */
184c0d4567Sbill %left OR
194c0d4567Sbill %left AND
204c0d4567Sbill %left EQ LT GT GEQ LEQ NEQ
214c0d4567Sbill %left ADD SUBT
224c0d4567Sbill %left MULT DIV REM
234c0d4567Sbill %left MCH
244c0d4567Sbill %left MATCH
254c0d4567Sbill %left SUBSTR
264c0d4567Sbill %left LENGTH INDEX
274c0d4567Sbill %%
284c0d4567Sbill
294c0d4567Sbill /* a single `expression' is evaluated and printed: */
304c0d4567Sbill
314c0d4567Sbill expression: expr NOARG = {
324c0d4567Sbill printf("%s\n", $1);
334c0d4567Sbill exit((!strcmp($1,"0")||!strcmp($1,"\0"))? 1: 0);
344c0d4567Sbill }
354c0d4567Sbill ;
364c0d4567Sbill
374c0d4567Sbill
384c0d4567Sbill expr: '(' expr ')' = { $$ = $2; }
394c0d4567Sbill | expr OR expr = { $$ = conj(OR, $1, $3); }
404c0d4567Sbill | expr AND expr = { $$ = conj(AND, $1, $3); }
414c0d4567Sbill | expr EQ expr = { $$ = rel(EQ, $1, $3); }
424c0d4567Sbill | expr GT expr = { $$ = rel(GT, $1, $3); }
434c0d4567Sbill | expr GEQ expr = { $$ = rel(GEQ, $1, $3); }
444c0d4567Sbill | expr LT expr = { $$ = rel(LT, $1, $3); }
454c0d4567Sbill | expr LEQ expr = { $$ = rel(LEQ, $1, $3); }
464c0d4567Sbill | expr NEQ expr = { $$ = rel(NEQ, $1, $3); }
474c0d4567Sbill | expr ADD expr = { $$ = arith(ADD, $1, $3); }
484c0d4567Sbill | expr SUBT expr = { $$ = arith(SUBT, $1, $3); }
494c0d4567Sbill | expr MULT expr = { $$ = arith(MULT, $1, $3); }
504c0d4567Sbill | expr DIV expr = { $$ = arith(DIV, $1, $3); }
514c0d4567Sbill | expr REM expr = { $$ = arith(REM, $1, $3); }
524c0d4567Sbill | expr MCH expr = { $$ = match($1, $3); }
534c0d4567Sbill | MATCH expr expr = { $$ = match($2, $3); }
544c0d4567Sbill | SUBSTR expr expr expr = { $$ = substr($2, $3, $4); }
554c0d4567Sbill | LENGTH expr = { $$ = length($2); }
564c0d4567Sbill | INDEX expr expr = { $$ = index($2, $3); }
574c0d4567Sbill | A_STRING
584c0d4567Sbill ;
594c0d4567Sbill %%
604c0d4567Sbill /* expression command */
616884d44aSbostic
626884d44aSbostic #ifndef lint
63*84651319Sbostic static char copyright[] =
64*84651319Sbostic "@(#) Copyright (c) 1991, 1993\n\
65*84651319Sbostic The Regents of the University of California. All rights reserved.\n";
666884d44aSbostic #endif /* not lint */
676884d44aSbostic
686884d44aSbostic #ifndef lint
69*84651319Sbostic static char sccsid[] = "@(#)expr.y 8.1 (Berkeley) 05/31/93";
706884d44aSbostic #endif /* not lint */
716884d44aSbostic
724c0d4567Sbill #include <stdio.h>
734c0d4567Sbill #define ESIZE 256
744c0d4567Sbill #define error(c) errxx(c)
754c0d4567Sbill #define EQL(x,y) !strcmp(x,y)
764c0d4567Sbill long atol();
774c0d4567Sbill char **Av;
784c0d4567Sbill int Ac;
794c0d4567Sbill int Argi;
804c0d4567Sbill
814c0d4567Sbill char Mstring[1][128];
824c0d4567Sbill char *malloc();
834c0d4567Sbill extern int nbra;
844c0d4567Sbill
main(argc,argv)854c0d4567Sbill main(argc, argv) char **argv; {
864c0d4567Sbill Ac = argc;
874c0d4567Sbill Argi = 1;
884c0d4567Sbill Av = argv;
894c0d4567Sbill yyparse();
904c0d4567Sbill }
914c0d4567Sbill
924c0d4567Sbill char *operators[] = { "|", "&", "+", "-", "*", "/", "%", ":",
934c0d4567Sbill "=", "==", "<", "<=", ">", ">=", "!=",
944c0d4567Sbill "match", "substr", "length", "index", "\0" };
954c0d4567Sbill int op[] = { OR, AND, ADD, SUBT, MULT, DIV, REM, MCH,
964c0d4567Sbill EQ, EQ, LT, LEQ, GT, GEQ, NEQ,
974c0d4567Sbill MATCH, SUBSTR, LENGTH, INDEX };
yylex()984c0d4567Sbill yylex() {
994c0d4567Sbill register char *p;
1004c0d4567Sbill register i;
1014c0d4567Sbill
1024c0d4567Sbill if(Argi >= Ac) return NOARG;
1034c0d4567Sbill
1044c0d4567Sbill p = Av[Argi++];
1054c0d4567Sbill
1064c0d4567Sbill if(*p == '(' || *p == ')')
1074c0d4567Sbill return (int)*p;
1084c0d4567Sbill for(i = 0; *operators[i]; ++i)
1094c0d4567Sbill if(EQL(operators[i], p))
1104c0d4567Sbill return op[i];
1114c0d4567Sbill
1124c0d4567Sbill yylval = p;
1134c0d4567Sbill return A_STRING;
1144c0d4567Sbill }
1154c0d4567Sbill
rel(op,r1,r2)1164c0d4567Sbill char *rel(op, r1, r2) register char *r1, *r2; {
117264c46cbSsam register long i;
1184c0d4567Sbill
1194c0d4567Sbill if(ematch(r1, "-*[0-9]*$") && ematch(r2, "[0-9]*$"))
1204c0d4567Sbill i = atol(r1) - atol(r2);
1214c0d4567Sbill else
1224c0d4567Sbill i = strcmp(r1, r2);
1234c0d4567Sbill switch(op) {
1244c0d4567Sbill case EQ: i = i==0; break;
1254c0d4567Sbill case GT: i = i>0; break;
1264c0d4567Sbill case GEQ: i = i>=0; break;
1274c0d4567Sbill case LT: i = i<0; break;
12856abee86Swnj case LEQ: i = i<=0; break;
1294c0d4567Sbill case NEQ: i = i!=0; break;
1304c0d4567Sbill }
1314c0d4567Sbill return i? "1": "0";
1324c0d4567Sbill }
1334c0d4567Sbill
arith(op,r1,r2)1344c0d4567Sbill char *arith(op, r1, r2) char *r1, *r2; {
1354c0d4567Sbill long i1, i2;
1364c0d4567Sbill register char *rv;
1374c0d4567Sbill
138a9c19d04Sbostic if(!((ematch(r1, "[0-9]*$") || ematch(r1, "-[0-9]*$")) &&
139a9c19d04Sbostic (ematch(r2, "[0-9]*$") || ematch(r2, "-[0-9]*$"))))
1404c0d4567Sbill yyerror("non-numeric argument");
1414c0d4567Sbill i1 = atol(r1);
1424c0d4567Sbill i2 = atol(r2);
1434c0d4567Sbill
1444c0d4567Sbill switch(op) {
1454c0d4567Sbill case ADD: i1 = i1 + i2; break;
1464c0d4567Sbill case SUBT: i1 = i1 - i2; break;
1474c0d4567Sbill case MULT: i1 = i1 * i2; break;
148a5a45b47Sralph case DIV:
149a5a45b47Sralph if (i2 != 0)
150a5a45b47Sralph i1 = i1 / i2;
151a5a45b47Sralph else
152a5a45b47Sralph yyerror("Divide by zero");
153a5a45b47Sralph break;
154a5a45b47Sralph case REM:
155a5a45b47Sralph if (i2 != 0)
156a5a45b47Sralph i1 = i1 % i2;
157a5a45b47Sralph else
158a5a45b47Sralph yyerror("Remainder by zero");
159a5a45b47Sralph break;
1604c0d4567Sbill }
1614c0d4567Sbill rv = malloc(16);
162f703d710Sbostic (void)sprintf(rv, "%ld", i1);
1634c0d4567Sbill return rv;
1644c0d4567Sbill }
conj(op,r1,r2)1654c0d4567Sbill char *conj(op, r1, r2) char *r1, *r2; {
1664c0d4567Sbill register char *rv;
1674c0d4567Sbill
1684c0d4567Sbill switch(op) {
1694c0d4567Sbill
1704c0d4567Sbill case OR:
1714c0d4567Sbill if(EQL(r1, "0")
1724c0d4567Sbill || EQL(r1, ""))
1734c0d4567Sbill if(EQL(r2, "0")
1744c0d4567Sbill || EQL(r2, ""))
1754c0d4567Sbill rv = "0";
1764c0d4567Sbill else
1774c0d4567Sbill rv = r2;
1784c0d4567Sbill else
1794c0d4567Sbill rv = r1;
1804c0d4567Sbill break;
1814c0d4567Sbill case AND:
1824c0d4567Sbill if(EQL(r1, "0")
1834c0d4567Sbill || EQL(r1, ""))
1844c0d4567Sbill rv = "0";
1854c0d4567Sbill else if(EQL(r2, "0")
1864c0d4567Sbill || EQL(r2, ""))
1874c0d4567Sbill rv = "0";
1884c0d4567Sbill else
1894c0d4567Sbill rv = r1;
1904c0d4567Sbill break;
1914c0d4567Sbill }
1924c0d4567Sbill return rv;
1934c0d4567Sbill }
1944c0d4567Sbill
substr(v,s,w)1954c0d4567Sbill char *substr(v, s, w) char *v, *s, *w; {
1964c0d4567Sbill register si, wi;
1974c0d4567Sbill register char *res;
1984c0d4567Sbill
1994c0d4567Sbill si = atol(s);
2004c0d4567Sbill wi = atol(w);
2014c0d4567Sbill while(--si) if(*v) ++v;
2024c0d4567Sbill
2034c0d4567Sbill res = v;
2044c0d4567Sbill
2054c0d4567Sbill while(wi--) if(*v) ++v;
2064c0d4567Sbill
2074c0d4567Sbill *v = '\0';
2084c0d4567Sbill return res;
2094c0d4567Sbill }
2104c0d4567Sbill
length(s)2114c0d4567Sbill char *length(s) register char *s; {
2124c0d4567Sbill register i = 0;
2134c0d4567Sbill register char *rv;
2144c0d4567Sbill
2154c0d4567Sbill while(*s++) ++i;
2164c0d4567Sbill
2174c0d4567Sbill rv = malloc(8);
218f703d710Sbostic (void)sprintf(rv, "%d", i);
2194c0d4567Sbill return rv;
2204c0d4567Sbill }
2214c0d4567Sbill
index(s,t)2224c0d4567Sbill char *index(s, t) char *s, *t; {
2234c0d4567Sbill register i, j;
2244c0d4567Sbill register char *rv;
2254c0d4567Sbill
2264c0d4567Sbill for(i = 0; s[i] ; ++i)
2274c0d4567Sbill for(j = 0; t[j] ; ++j)
2284c0d4567Sbill if(s[i]==t[j]) {
229f703d710Sbostic (void)sprintf(rv = malloc(8), "%d", ++i);
2304c0d4567Sbill return rv;
2314c0d4567Sbill }
2324c0d4567Sbill return "0";
2334c0d4567Sbill }
2344c0d4567Sbill
match(s,p)2354c0d4567Sbill char *match(s, p)
2364c0d4567Sbill {
2374c0d4567Sbill register char *rv;
2384c0d4567Sbill
239f703d710Sbostic (void)sprintf(rv = malloc(8), "%d", ematch(s, p));
2404c0d4567Sbill if(nbra) {
2414c0d4567Sbill rv = malloc(strlen(Mstring[0])+1);
2424c0d4567Sbill strcpy(rv, Mstring[0]);
2434c0d4567Sbill }
2444c0d4567Sbill return rv;
2454c0d4567Sbill }
2464c0d4567Sbill
2474c0d4567Sbill #define INIT register char *sp = instring;
2484c0d4567Sbill #define GETC() (*sp++)
2494c0d4567Sbill #define PEEKC() (*sp)
2504c0d4567Sbill #define UNGETC(c) (--sp)
2514c0d4567Sbill #define RETURN(c) return
2524c0d4567Sbill #define ERROR(c) errxx(c)
2534c0d4567Sbill
2544c0d4567Sbill
ematch(s,p)2554c0d4567Sbill ematch(s, p)
2564c0d4567Sbill char *s;
2574c0d4567Sbill register char *p;
2584c0d4567Sbill {
2594c0d4567Sbill static char expbuf[ESIZE];
2604c0d4567Sbill char *compile();
2614c0d4567Sbill register num;
2624c0d4567Sbill extern char *braslist[], *braelist[], *loc2;
2634c0d4567Sbill
264e74403baSralph compile(p, expbuf, &expbuf[ESIZE], 0);
2654c0d4567Sbill if(nbra > 1)
2664c0d4567Sbill yyerror("Too many '\\('s");
2674c0d4567Sbill if(advance(s, expbuf)) {
2684c0d4567Sbill if(nbra == 1) {
2694c0d4567Sbill p = braslist[0];
2704c0d4567Sbill num = braelist[0] - p;
2714c0d4567Sbill strncpy(Mstring[0], p, num);
2724c0d4567Sbill Mstring[0][num] = '\0';
2734c0d4567Sbill }
2744c0d4567Sbill return(loc2-s);
2754c0d4567Sbill }
2764c0d4567Sbill return(0);
2774c0d4567Sbill }
2784c0d4567Sbill
errxx(c)2794c0d4567Sbill errxx(c)
2804c0d4567Sbill {
2814c0d4567Sbill yyerror("RE error");
2824c0d4567Sbill }
2834c0d4567Sbill
2844c0d4567Sbill #define CBRA 2
2854c0d4567Sbill #define CCHR 4
2864c0d4567Sbill #define CDOT 8
2874c0d4567Sbill #define CCL 12
2884c0d4567Sbill #define CDOL 20
2894c0d4567Sbill #define CEOF 22
2904c0d4567Sbill #define CKET 24
2914c0d4567Sbill #define CBACK 36
2924c0d4567Sbill
2934c0d4567Sbill #define STAR 01
2944c0d4567Sbill #define RNGE 03
2954c0d4567Sbill
2964c0d4567Sbill #define NBRA 9
2974c0d4567Sbill
2984c0d4567Sbill #define PLACE(c) ep[c >> 3] |= bittab[c & 07]
2994c0d4567Sbill #define ISTHERE(c) (ep[c >> 3] & bittab[c & 07])
3004c0d4567Sbill
3014c0d4567Sbill char *braslist[NBRA];
3024c0d4567Sbill char *braelist[NBRA];
3034c0d4567Sbill int nbra;
3044c0d4567Sbill char *loc1, *loc2, *locs;
3054c0d4567Sbill int sed;
3064c0d4567Sbill
3074c0d4567Sbill int circf;
3084c0d4567Sbill int low;
3094c0d4567Sbill int size;
3104c0d4567Sbill
3114c0d4567Sbill char bittab[] = {
3124c0d4567Sbill 1,
3134c0d4567Sbill 2,
3144c0d4567Sbill 4,
3154c0d4567Sbill 8,
3164c0d4567Sbill 16,
3174c0d4567Sbill 32,
3184c0d4567Sbill 64,
3194c0d4567Sbill 128
3204c0d4567Sbill };
3214c0d4567Sbill
3224c0d4567Sbill char *
compile(instring,ep,endbuf,seof)3234c0d4567Sbill compile(instring, ep, endbuf, seof)
3244c0d4567Sbill register char *ep;
3254c0d4567Sbill char *instring, *endbuf;
3264c0d4567Sbill {
3274c0d4567Sbill INIT /* Dependent declarations and initializations */
3284c0d4567Sbill register c;
3294c0d4567Sbill register eof = seof;
3304c0d4567Sbill char *lastep = instring;
3314c0d4567Sbill int cclcnt;
3324c0d4567Sbill char bracket[NBRA], *bracketp;
3334c0d4567Sbill int closed;
3344c0d4567Sbill char neg;
3354c0d4567Sbill int lc;
3364c0d4567Sbill int i, cflg;
3374c0d4567Sbill
3384c0d4567Sbill lastep = 0;
3394c0d4567Sbill if((c = GETC()) == eof) {
3404c0d4567Sbill if(*ep == 0 && !sed)
3414c0d4567Sbill ERROR(41);
3424c0d4567Sbill RETURN(ep);
3434c0d4567Sbill }
3444c0d4567Sbill bracketp = bracket;
3454c0d4567Sbill circf = closed = nbra = 0;
3464c0d4567Sbill if (c == '^')
3474c0d4567Sbill circf++;
3484c0d4567Sbill else
3494c0d4567Sbill UNGETC(c);
3504c0d4567Sbill for (;;) {
3514c0d4567Sbill if (ep >= endbuf)
3524c0d4567Sbill ERROR(50);
3534c0d4567Sbill if((c = GETC()) != '*' && ((c != '\\') || (PEEKC() != '{')))
3544c0d4567Sbill lastep = ep;
3554c0d4567Sbill if (c == eof) {
3564c0d4567Sbill *ep++ = CEOF;
3574c0d4567Sbill RETURN(ep);
3584c0d4567Sbill }
3594c0d4567Sbill switch (c) {
3604c0d4567Sbill
3614c0d4567Sbill case '.':
3624c0d4567Sbill *ep++ = CDOT;
3634c0d4567Sbill continue;
3644c0d4567Sbill
3654c0d4567Sbill case '\n':
3664c0d4567Sbill ERROR(36);
3674c0d4567Sbill case '*':
3684c0d4567Sbill if (lastep==0 || *lastep==CBRA || *lastep==CKET)
3694c0d4567Sbill goto defchar;
3704c0d4567Sbill *lastep |= STAR;
3714c0d4567Sbill continue;
3724c0d4567Sbill
3734c0d4567Sbill case '$':
3744c0d4567Sbill if(PEEKC() != eof)
3754c0d4567Sbill goto defchar;
3764c0d4567Sbill *ep++ = CDOL;
3774c0d4567Sbill continue;
3784c0d4567Sbill
3794c0d4567Sbill case '[':
3804c0d4567Sbill if(&ep[17] >= endbuf)
3814c0d4567Sbill ERROR(50);
3824c0d4567Sbill
3834c0d4567Sbill *ep++ = CCL;
3844c0d4567Sbill lc = 0;
3854c0d4567Sbill for(i = 0; i < 16; i++)
3864c0d4567Sbill ep[i] = 0;
3874c0d4567Sbill
3884c0d4567Sbill neg = 0;
3894c0d4567Sbill if((c = GETC()) == '^') {
3904c0d4567Sbill neg = 1;
3914c0d4567Sbill c = GETC();
3924c0d4567Sbill }
3934c0d4567Sbill
3944c0d4567Sbill do {
3954c0d4567Sbill if(c == '\0' || c == '\n')
3964c0d4567Sbill ERROR(49);
3974c0d4567Sbill if(c == '-' && lc != 0) {
3984c0d4567Sbill if ((c = GETC()) == ']') {
3994c0d4567Sbill PLACE('-');
4004c0d4567Sbill break;
4014c0d4567Sbill }
4024c0d4567Sbill while(lc < c) {
4034c0d4567Sbill PLACE(lc);
4044c0d4567Sbill lc++;
4054c0d4567Sbill }
4064c0d4567Sbill }
4074c0d4567Sbill lc = c;
4084c0d4567Sbill PLACE(c);
4094c0d4567Sbill } while((c = GETC()) != ']');
4104c0d4567Sbill if(neg) {
4114c0d4567Sbill for(cclcnt = 0; cclcnt < 16; cclcnt++)
4124c0d4567Sbill ep[cclcnt] ^= -1;
4134c0d4567Sbill ep[0] &= 0376;
4144c0d4567Sbill }
4154c0d4567Sbill
4164c0d4567Sbill ep += 16;
4174c0d4567Sbill
4184c0d4567Sbill continue;
4194c0d4567Sbill
4204c0d4567Sbill case '\\':
4214c0d4567Sbill switch(c = GETC()) {
4224c0d4567Sbill
4234c0d4567Sbill case '(':
4244c0d4567Sbill if(nbra >= NBRA)
4254c0d4567Sbill ERROR(43);
4264c0d4567Sbill *bracketp++ = nbra;
4274c0d4567Sbill *ep++ = CBRA;
4284c0d4567Sbill *ep++ = nbra++;
4294c0d4567Sbill continue;
4304c0d4567Sbill
4314c0d4567Sbill case ')':
4324c0d4567Sbill if(bracketp <= bracket)
4334c0d4567Sbill ERROR(42);
4344c0d4567Sbill *ep++ = CKET;
4354c0d4567Sbill *ep++ = *--bracketp;
4364c0d4567Sbill closed++;
4374c0d4567Sbill continue;
4384c0d4567Sbill
4394c0d4567Sbill case '{':
4404c0d4567Sbill if(lastep == (char *) (0))
4414c0d4567Sbill goto defchar;
4424c0d4567Sbill *lastep |= RNGE;
4434c0d4567Sbill cflg = 0;
4444c0d4567Sbill nlim:
4454c0d4567Sbill c = GETC();
4464c0d4567Sbill i = 0;
4474c0d4567Sbill do {
4484c0d4567Sbill if ('0' <= c && c <= '9')
4494c0d4567Sbill i = 10 * i + c - '0';
4504c0d4567Sbill else
4514c0d4567Sbill ERROR(16);
4524c0d4567Sbill } while(((c = GETC()) != '\\') && (c != ','));
4534c0d4567Sbill if (i > 255)
4544c0d4567Sbill ERROR(11);
4554c0d4567Sbill *ep++ = i;
4564c0d4567Sbill if (c == ',') {
4574c0d4567Sbill if(cflg++)
4584c0d4567Sbill ERROR(44);
4594c0d4567Sbill if((c = GETC()) == '\\')
4604c0d4567Sbill *ep++ = 255;
4614c0d4567Sbill else {
4624c0d4567Sbill UNGETC(c);
4634c0d4567Sbill goto nlim; /* get 2'nd number */
4644c0d4567Sbill }
4654c0d4567Sbill }
4664c0d4567Sbill if(GETC() != '}')
4674c0d4567Sbill ERROR(45);
4684c0d4567Sbill if(!cflg) /* one number */
4694c0d4567Sbill *ep++ = i;
4704c0d4567Sbill else if((ep[-1] & 0377) < (ep[-2] & 0377))
4714c0d4567Sbill ERROR(46);
4724c0d4567Sbill continue;
4734c0d4567Sbill
4744c0d4567Sbill case '\n':
4754c0d4567Sbill ERROR(36);
4764c0d4567Sbill
4774c0d4567Sbill case 'n':
4784c0d4567Sbill c = '\n';
4794c0d4567Sbill goto defchar;
4804c0d4567Sbill
4814c0d4567Sbill default:
4824c0d4567Sbill if(c >= '1' && c <= '9') {
4834c0d4567Sbill if((c -= '1') >= closed)
4844c0d4567Sbill ERROR(25);
4854c0d4567Sbill *ep++ = CBACK;
4864c0d4567Sbill *ep++ = c;
4874c0d4567Sbill continue;
4884c0d4567Sbill }
4894c0d4567Sbill }
4904c0d4567Sbill /* Drop through to default to use \ to turn off special chars */
4914c0d4567Sbill
4924c0d4567Sbill defchar:
4934c0d4567Sbill default:
4944c0d4567Sbill lastep = ep;
4954c0d4567Sbill *ep++ = CCHR;
4964c0d4567Sbill *ep++ = c;
4974c0d4567Sbill }
4984c0d4567Sbill }
4994c0d4567Sbill }
5004c0d4567Sbill
step(p1,p2)5014c0d4567Sbill step(p1, p2)
5024c0d4567Sbill register char *p1, *p2;
5034c0d4567Sbill {
5044c0d4567Sbill register c;
5054c0d4567Sbill
5064c0d4567Sbill if (circf) {
5074c0d4567Sbill loc1 = p1;
5084c0d4567Sbill return(advance(p1, p2));
5094c0d4567Sbill }
5104c0d4567Sbill /* fast check for first character */
5114c0d4567Sbill if (*p2==CCHR) {
5124c0d4567Sbill c = p2[1];
5134c0d4567Sbill do {
5144c0d4567Sbill if (*p1 != c)
5154c0d4567Sbill continue;
5164c0d4567Sbill if (advance(p1, p2)) {
5174c0d4567Sbill loc1 = p1;
5184c0d4567Sbill return(1);
5194c0d4567Sbill }
5204c0d4567Sbill } while (*p1++);
5214c0d4567Sbill return(0);
5224c0d4567Sbill }
5234c0d4567Sbill /* regular algorithm */
5244c0d4567Sbill do {
5254c0d4567Sbill if (advance(p1, p2)) {
5264c0d4567Sbill loc1 = p1;
5274c0d4567Sbill return(1);
5284c0d4567Sbill }
5294c0d4567Sbill } while (*p1++);
5304c0d4567Sbill return(0);
5314c0d4567Sbill }
5324c0d4567Sbill
advance(lp,ep)5334c0d4567Sbill advance(lp, ep)
5344c0d4567Sbill register char *lp, *ep;
5354c0d4567Sbill {
5364c0d4567Sbill register char *curlp;
5374c0d4567Sbill char c;
5384c0d4567Sbill char *bbeg;
5394c0d4567Sbill int ct;
5404c0d4567Sbill
5414c0d4567Sbill for (;;) switch (*ep++) {
5424c0d4567Sbill
5434c0d4567Sbill case CCHR:
5444c0d4567Sbill if (*ep++ == *lp++)
5454c0d4567Sbill continue;
5464c0d4567Sbill return(0);
5474c0d4567Sbill
5484c0d4567Sbill case CDOT:
5494c0d4567Sbill if (*lp++)
5504c0d4567Sbill continue;
5514c0d4567Sbill return(0);
5524c0d4567Sbill
5534c0d4567Sbill case CDOL:
5544c0d4567Sbill if (*lp==0)
5554c0d4567Sbill continue;
5564c0d4567Sbill return(0);
5574c0d4567Sbill
5584c0d4567Sbill case CEOF:
5594c0d4567Sbill loc2 = lp;
5604c0d4567Sbill return(1);
5614c0d4567Sbill
5624c0d4567Sbill case CCL:
5634c0d4567Sbill c = *lp++ & 0177;
5644c0d4567Sbill if(ISTHERE(c)) {
5654c0d4567Sbill ep += 16;
5664c0d4567Sbill continue;
5674c0d4567Sbill }
5684c0d4567Sbill return(0);
5694c0d4567Sbill case CBRA:
5704c0d4567Sbill braslist[*ep++] = lp;
5714c0d4567Sbill continue;
5724c0d4567Sbill
5734c0d4567Sbill case CKET:
5744c0d4567Sbill braelist[*ep++] = lp;
5754c0d4567Sbill continue;
5764c0d4567Sbill
5774c0d4567Sbill case CCHR|RNGE:
5784c0d4567Sbill c = *ep++;
5794c0d4567Sbill getrnge(ep);
5804c0d4567Sbill while(low--)
5814c0d4567Sbill if(*lp++ != c)
5824c0d4567Sbill return(0);
5834c0d4567Sbill curlp = lp;
5844c0d4567Sbill while(size--)
5854c0d4567Sbill if(*lp++ != c)
5864c0d4567Sbill break;
5874c0d4567Sbill if(size < 0)
5884c0d4567Sbill lp++;
5894c0d4567Sbill ep += 2;
5904c0d4567Sbill goto star;
5914c0d4567Sbill
5924c0d4567Sbill case CDOT|RNGE:
5934c0d4567Sbill getrnge(ep);
5944c0d4567Sbill while(low--)
5954c0d4567Sbill if(*lp++ == '\0')
5964c0d4567Sbill return(0);
5974c0d4567Sbill curlp = lp;
5984c0d4567Sbill while(size--)
5994c0d4567Sbill if(*lp++ == '\0')
6004c0d4567Sbill break;
6014c0d4567Sbill if(size < 0)
6024c0d4567Sbill lp++;
6034c0d4567Sbill ep += 2;
6044c0d4567Sbill goto star;
6054c0d4567Sbill
6064c0d4567Sbill case CCL|RNGE:
6074c0d4567Sbill getrnge(ep + 16);
6084c0d4567Sbill while(low--) {
6094c0d4567Sbill c = *lp++ & 0177;
6104c0d4567Sbill if(!ISTHERE(c))
6114c0d4567Sbill return(0);
6124c0d4567Sbill }
6134c0d4567Sbill curlp = lp;
6144c0d4567Sbill while(size--) {
6154c0d4567Sbill c = *lp++ & 0177;
6164c0d4567Sbill if(!ISTHERE(c))
6174c0d4567Sbill break;
6184c0d4567Sbill }
6194c0d4567Sbill if(size < 0)
6204c0d4567Sbill lp++;
6214c0d4567Sbill ep += 18; /* 16 + 2 */
6224c0d4567Sbill goto star;
6234c0d4567Sbill
6244c0d4567Sbill case CBACK:
6254c0d4567Sbill bbeg = braslist[*ep];
6264c0d4567Sbill ct = braelist[*ep++] - bbeg;
6274c0d4567Sbill
6284c0d4567Sbill if(ecmp(bbeg, lp, ct)) {
6294c0d4567Sbill lp += ct;
6304c0d4567Sbill continue;
6314c0d4567Sbill }
6324c0d4567Sbill return(0);
6334c0d4567Sbill
6344c0d4567Sbill case CBACK|STAR:
6354c0d4567Sbill bbeg = braslist[*ep];
6364c0d4567Sbill ct = braelist[*ep++] - bbeg;
6374c0d4567Sbill curlp = lp;
6384c0d4567Sbill while(ecmp(bbeg, lp, ct))
6394c0d4567Sbill lp += ct;
6404c0d4567Sbill
6414c0d4567Sbill while(lp >= curlp) {
6424c0d4567Sbill if(advance(lp, ep)) return(1);
6434c0d4567Sbill lp -= ct;
6444c0d4567Sbill }
6454c0d4567Sbill return(0);
6464c0d4567Sbill
6474c0d4567Sbill
6484c0d4567Sbill case CDOT|STAR:
6494c0d4567Sbill curlp = lp;
6504c0d4567Sbill while (*lp++);
6514c0d4567Sbill goto star;
6524c0d4567Sbill
6534c0d4567Sbill case CCHR|STAR:
6544c0d4567Sbill curlp = lp;
6554c0d4567Sbill while (*lp++ == *ep);
6564c0d4567Sbill ep++;
6574c0d4567Sbill goto star;
6584c0d4567Sbill
6594c0d4567Sbill case CCL|STAR:
6604c0d4567Sbill curlp = lp;
6614c0d4567Sbill do {
6624c0d4567Sbill c = *lp++ & 0177;
6634c0d4567Sbill } while(ISTHERE(c));
6644c0d4567Sbill ep += 16;
6654c0d4567Sbill goto star;
6664c0d4567Sbill
6674c0d4567Sbill star:
6684c0d4567Sbill do {
6694c0d4567Sbill if(--lp == locs)
6704c0d4567Sbill break;
6714c0d4567Sbill if (advance(lp, ep))
6724c0d4567Sbill return(1);
6734c0d4567Sbill } while (lp > curlp);
6744c0d4567Sbill return(0);
6754c0d4567Sbill
6764c0d4567Sbill }
6774c0d4567Sbill }
6784c0d4567Sbill
getrnge(str)6794c0d4567Sbill getrnge(str)
6804c0d4567Sbill register char *str;
6814c0d4567Sbill {
6824c0d4567Sbill low = *str++ & 0377;
683d0e3910bSbostic size = (*str & 0377) == 255 ? 20000 : (*str & 0377) - low;
6844c0d4567Sbill }
6854c0d4567Sbill
ecmp(a,b,count)6864c0d4567Sbill ecmp(a, b, count)
6874c0d4567Sbill register char *a, *b;
6884c0d4567Sbill register count;
6894c0d4567Sbill {
6904c0d4567Sbill if(a == b) /* should have been caught in compile() */
6914c0d4567Sbill error(51);
6924c0d4567Sbill while(count--)
6934c0d4567Sbill if(*a++ != *b++) return(0);
6944c0d4567Sbill return(1);
6954c0d4567Sbill }
6964c0d4567Sbill
yyerror(s)6974c0d4567Sbill yyerror(s)
6984c0d4567Sbill
6994c0d4567Sbill {
7004c0d4567Sbill fprintf(stderr, "%s\n", s);
7014c0d4567Sbill exit(2);
7024c0d4567Sbill }
703