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