]> diplodocus.org Git - nmh/blob - docs/historical/mh-nov-1983/cmds/grep.c
Removed --depth 1 from git clone invocation.
[nmh] / docs / historical / mh-nov-1983 / cmds / grep.c
1 #include <stdio.h>
2 #define CCHR 2
3 #define CDOT 4
4 #define CCL 6
5 #define NCCL 8
6 #define CDOL 10
7 #define CEOF 11
8
9 #define STAR 01
10
11 #define LBSIZE 1024
12 #define ESIZE 256
13
14 char ibuf[BUFSIZ];
15 char expbuf[ESIZE];
16 char linebuf[LBSIZE+1];
17 int circf;
18
19 char cc[] = {
20 0000,0001,0002,0003,0004,0005,0006,0007,
21 0010,0011,0012,0013,0014,0015,0016,0017,
22 0020,0021,0022,0023,0024,0025,0026,0027,
23 0030,0031,0032,0033,0034,0035,0036,0037,
24 0040,0041,0042,0043,0044,0045,0046,0047,
25 0050,0051,0052,0053,0054,0055,0056,0057,
26 0060,0061,0062,0063,0064,0065,0066,0067,
27 0070,0071,0072,0073,0074,0075,0076,0077,
28 0100,0141,0142,0143,0144,0145,0146,0147,
29 0150,0151,0152,0153,0154,0155,0156,0157,
30 0160,0161,0162,0163,0164,0165,0166,0167,
31 0170,0171,0172,0133,0134,0135,0136,0137,
32 0140,0141,0142,0143,0144,0145,0146,0147,
33 0150,0151,0152,0153,0154,0155,0156,0157,
34 0160,0161,0162,0163,0164,0165,0166,0167,
35 0170,0171,0172,0173,0174,0175,0176,0177,
36 };
37
38
39 compile(astr)
40 char *astr;
41 {
42 register c;
43 register char *ep, *sp;
44 char *lastep;
45 int cclcnt;
46
47 ep = expbuf;
48 sp = astr;
49 if (*sp == '^') {
50 circf++;
51 sp++;
52 }
53 for (;;) {
54 if (ep >= &expbuf[ESIZE])
55 goto cerror;
56 if ((c = *sp++) != '*')
57 lastep = ep;
58 switch (c) {
59
60 case '\0':
61 *ep++ = CEOF;
62 return(1);
63
64 case '.':
65 *ep++ = CDOT;
66 continue;
67
68 case '*':
69 if (lastep==0)
70 goto defchar;
71 *lastep |= STAR;
72 continue;
73
74 case '$':
75 if (*sp != '\0')
76 goto defchar;
77 *ep++ = CDOL;
78 continue;
79
80 case '[':
81 *ep++ = CCL;
82 *ep++ = 0;
83 cclcnt = 1;
84 if ((c = *sp++) == '^') {
85 c = *sp++;
86 ep[-2] = NCCL;
87 }
88 do {
89 *ep++ = c;
90 cclcnt++;
91 if (c=='\0' || ep >= &expbuf[ESIZE])
92 goto cerror;
93 } while ((c = *sp++) != ']');
94 lastep[1] = cclcnt;
95 continue;
96
97 case '\\':
98 if ((c = *sp++) == '\0')
99 goto cerror;
100 defchar:
101 default:
102 *ep++ = CCHR;
103 *ep++ = c;
104 }
105 }
106 cerror:
107 return(0);
108 }
109
110
111 execute(file)
112 char *file;
113 {
114 register char *p1, *p2;
115 register c;
116 int f, body, lf;
117 char *ebp, *cbp;
118
119 if ((f = open(file, 0)) < 0) {
120 fprintf(stderr, "Grep: Can't open %s\n", file);
121 return(0);
122 }
123 body = 0;
124 ebp = ibuf;
125 cbp = ibuf;
126 for (;;) {
127 p1 = linebuf;
128 p2 = cbp;
129 lf = 0;
130 for (;;) {
131 if (p2 >= ebp) {
132 if ((c = read(f, ibuf, sizeof ibuf)) <= 0) {
133 close(f);
134 if(lf) break; /* bodyless comp! */
135 return(0);
136 }
137 p2 = ibuf;
138 ebp = ibuf+c;
139 }
140 c = *p2++;
141 if(lf) if(c != ' ' && c != '\t') {
142 --p2;
143 break;
144 } else
145 lf = 0;
146 if (c == '\n')
147 if(body)
148 break;
149 else {
150 if(lf) {
151 body++;
152 break;
153 }
154 lf++;
155 c = ' ';
156 }
157 if(c && p1 < &linebuf[LBSIZE-1])
158 *p1++ = c;
159 }
160 *p1++ = 0;
161 cbp = p2;
162 p1 = linebuf;
163 p2 = expbuf;
164 if (circf) {
165 if (advance(p1, p2))
166 goto found;
167 continue;
168 }
169 /* fast check for first character */
170 if (*p2==CCHR) {
171 c = p2[1];
172 do {
173 if(*p1==c || cc[*p1]==c)
174 if (advance(p1, p2))
175 goto found;
176 } while (*p1++);
177 continue;
178 }
179 /* regular algorithm */
180 do {
181 if (advance(p1, p2))
182 goto found;
183 } while (*p1++);
184 continue;
185 found:
186 close(f);
187 return(1);
188 }
189 }
190
191
192 advance(alp, aep)
193 char *alp, *aep;
194 {
195 register char *lp, *ep, *curlp;
196 char *nextep;
197
198 lp = alp;
199 ep = aep;
200 for (;;) switch (*ep++) {
201
202 case CCHR:
203 if (*ep++ == *lp++ || ep[-1] == cc[lp[-1]])
204 continue;
205 return(0);
206
207 case CDOT:
208 if (*lp++)
209 continue;
210 return(0);
211
212 case CDOL:
213 if (*lp==0)
214 continue;
215 return(0);
216
217 case CEOF:
218 return(1);
219
220 case CCL:
221 if (cclass(ep, *lp++, 1)) {
222 ep += *ep;
223 continue;
224 }
225 return(0);
226
227 case NCCL:
228 if (cclass(ep, *lp++, 0)) {
229 ep += *ep;
230 continue;
231 }
232 return(0);
233
234 case CDOT|STAR:
235 curlp = lp;
236 while (*lp++);
237 goto star;
238
239 case CCHR|STAR:
240 curlp = lp;
241 while (*lp++ == *ep || cc[lp[-1]] == *ep) ;
242 ep++;
243 goto star;
244
245 case CCL|STAR:
246 case NCCL|STAR:
247 curlp = lp;
248 while (cclass(ep, *lp++, ep[-1]==(CCL|STAR)));
249 ep += *ep;
250 goto star;
251
252 star:
253 do {
254 lp--;
255 if (advance(lp, ep))
256 return(1);
257 } while (lp > curlp);
258 return(0);
259
260 default:
261 printf("RE botch\n");
262 return(0);
263 }
264 }
265
266
267 cclass(aset, ac, af)
268 char *aset;
269 {
270 register char *set, c;
271 register n;
272
273 set = aset;
274 if ((c = ac) == 0)
275 return(0);
276 n = *set++;
277 while (--n)
278 if (*set++ == c)
279 return(af);
280 return(!af);
281 }