1 /* $Id: stream.c,v 1.28 2020-11-19 02:31:31 phil Exp $ */
2 
3 #ifdef HAVE_CONFIG_H
4 #include "config.h"
5 #endif /* HAVE_CONFIG_H defined */
6 
7 #include "h.h"
8 #include "snotypes.h"
9 #include "syntab.h"
10 
11 #include "macros.h"
12 #include "equ.h"
13 #include "res.h"
14 #include "data.h"			/* for STYPE */
15 
16 #ifdef DEBUG
17 #define DEBUGF(lev, x) if (lev <= DEBUG) printf x
18 #else  /* DEBUG not defined */
19 #define DEBUGF(lev, x)
20 #endif /* DEBUG not defined */
21 
22 enum stream_ret
stream(struct spec * sp1,struct spec * sp2,struct syntab * tp)23 stream(
24     struct spec *sp1,			/* OUT: prefix */
25     struct spec *sp2,			/* IN: string OUT: remainder */
26     struct syntab *tp) {
27     register unsigned char *cp;
28     enum stream_ret ret;
29     register int len;
30     int_t put;
31 
32     len = S_L(sp2);
33     cp = (unsigned char *)S_SP(sp2);
34     put = 0;				/* XXX in case no puts?? */
35 
36     DEBUGF(1,("stream"));
37     DEBUGF(10,(" '%*s'", len, cp));
38     DEBUGF(1,(" table %s\n", tp->name ));
39 
40     for (; len > 0; cp++, len--) {
41 	register const struct acts *ap;
42 	unsigned aindex;
43 
44 	aindex = tp->chrs[*cp];
45 
46 	DEBUGF(2,(" '%c' (%d)", *cp, *cp ));
47 
48 	/*
49 	 * handle CONTIN quickly (95% of time)
50 	 * always has magic value zero.
51 	 * 9/9/97
52 	 */
53 	if (aindex == 0) {
54 	    DEBUGF(2,(" CONTIN\n"));
55 	    continue;
56 	}
57 
58 	ap = tp->actions + (aindex - 1);
59 
60 	/* token can never occur with CONTIN or ERROR? */
61 	if (ap->put) {
62 	    put = ap->put;
63 	    DEBUGF(2,(" put %d", put ));
64 	}
65 
66 #ifdef DEBUG
67 	switch (ap->act) {
68 	case AC_CONTIN:
69 	    DEBUGF(2,(" CONTIN\n"));	/* shoudl not happen */
70 	    break;
71 	case AC_STOP:
72 	    DEBUGF(2,(" STOP\n"));
73 	    break;
74 	case AC_STOPSH:
75 	    DEBUGF(2,(" STOPSH\n"));
76 	    break;
77 	case AC_ERROR:
78 	    DEBUGF(2,(" ERROR\n"));
79 	    break;
80 	case AC_GOTO:
81 	    DEBUGF(2,(" goto %s\n", ap->go->name));
82 	    break;
83 	}
84 #endif /* DEBUG defined */
85 
86 	switch (ap->act) {
87 	case AC_CONTIN:			/* should not happen */
88 	    break;
89 	case AC_STOP:
90 	    cp++; len--;		/* accept */
91 	    /* FALL */
92 	case AC_STOPSH:
93 	    ret = ST_STOP;
94 	    goto break_loop;
95 	case AC_ERROR:
96 	    D_A(STYPE) = 0;
97 	    return ST_ERROR;		/* immediate return! */
98 	case AC_GOTO:
99 	    tp = ap->go;		/* goto new table */
100 	    break;
101 	}
102     } /* for */
103     /* here when out of subject */
104     ret = ST_EOS;
105 
106  break_loop:
107     D_A(STYPE) = put;
108     len = S_L(sp2) - len;		/* get match length */
109 
110     _SPEC(sp1) = _SPEC(sp2);		/* copy spec for prefix */
111     S_L(sp1) = len;			/* set prefix length */
112 
113     if (ret != ST_EOS)
114 	S_O(sp2) += len;		/* bump suffix offset */
115 
116     S_L(sp2) -= len;			/* adjust suffix length */
117 
118     return ret;
119 }
120 
121 /* new 9/9/97; hide CONTIN crock */
122 static int
findact(enum action act,struct syntab * tp)123 findact(enum action act, struct syntab *tp) {
124     const struct acts *ap;
125     register int j;
126 
127     /* CONTIN is always zero, others one-based */
128     if (act == AC_CONTIN)
129 	return 0;
130 
131     /* find action index in list (SNABTB has one of each action type) */
132     for (j = 1, ap = tp->actions; ; j++, ap++)
133 	if (ap->act == act)
134 	    break;
135 
136     return j;
137 }
138 
139 /* 10/28/93 */
140 void
clertb(struct syntab * tp,enum action act)141 clertb(struct syntab *tp, enum action act) {
142     unsigned int i;
143     int j;
144     union {
145 	long l;
146 	char c[sizeof(long)];
147     } u;
148     register long *lp, l;
149 
150     j = findact(act, tp);
151     /* setup long's worth of chars */
152     for (i = 0; i < sizeof(u.c); i++)
153 	u.c[i] = j;
154 
155     /* stamp out long's with unrolled loop */
156     l = u.l;
157     lp = (long *) tp->chrs;
158     i = CHARSET / sizeof(u.c) / 8;
159     do {
160 	/* most ISA's have index+offset; RISC's tend not to have autoinc */
161 	lp[0] = l;
162 	lp[1] = l;
163 	lp[2] = l;
164 	lp[3] = l;
165 	lp[4] = l;
166 	lp[5] = l;
167 	lp[6] = l;
168 	lp[7] = l;
169 	lp += 8;
170     } while (--i != 0);
171 }
172 
173 /* 10/28/93 */
174 void
plugtb(struct syntab * tp,enum action act,struct spec * sp)175 plugtb(struct syntab *tp, enum action act, struct spec *sp) {
176     register unsigned char *cp;
177     register int len;
178     register int j;
179 
180     len = S_L(sp);
181     cp = (unsigned char *)S_SP(sp);
182 
183     j = findact(act, tp);
184     while (len > 0) {
185 	tp->chrs[*cp++] = j;
186 	len--;
187     }
188 }
189 
190 /* 8/5/97 [PLB59] */
191 int
any(struct spec * sp,struct descr * dp)192 any(struct spec *sp,			/* subject */
193     struct descr *dp) {			/* (not)any arg str */
194     register unsigned char c, *cp;
195     struct descr *vp;
196     register int i;
197 
198     c = *(unsigned char *)S_SP(sp);	/* get next subject char */
199     vp = (struct descr *)D_A(dp);	/* ptr to char set var */
200     cp = ((unsigned char *)vp) + BCDFLD; /* ptr to char set */
201     i = D_V(vp);			/* length of char set */
202 
203     while (i > 0) {
204 	if (*cp == c)
205 	    return 1;
206 	cp++;
207 	i--;
208     }
209     return 0;
210 }
211