Bell 32V development
[unix-history] / usr / src / cmd / sed / sed1.c
CommitLineData
f0d89bd2
TL
1#include <stdio.h>
2#include "sed.h"
3
4execute(file)
5char *file;
6{
7 register char *p1, *p2;
8 register union reptr *ipc;
9 int c;
10 char *execp;
11
12 if (file) {
13 if ((f = open(file, 0)) < 0) {
14 fprintf(stderr, "Can't open %s\n", file);
15 }
16 } else
17 f = 0;
18
19 ebp = ibuf;
20 cbp = ibuf;
21
22 if(pending) {
23 ipc = pending;
24 pending = 0;
25 goto yes;
26 }
27
28 for(;;) {
29 if((execp = gline(linebuf)) == badp) {
30 close(f);
31 return;
32 }
33 spend = execp;
34
35 for(ipc = ptrspace; ipc->command; ) {
36
37 p1 = ipc->ad1;
38 p2 = ipc->ad2;
39
40 if(p1) {
41
42 if(ipc->inar) {
43 if(*p2 == CEND) {
44 p1 = 0;
45 } else if(*p2 == CLNUM) {
46 c = p2[1];
47 if(lnum > tlno[c]) {
48 ipc->inar = 0;
49 if(ipc->negfl)
50 goto yes;
51 ipc++;
52 continue;
53 }
54 if(lnum == tlno[c]) {
55 ipc->inar = 0;
56 }
57 } else if(match(p2, 0)) {
58 ipc->inar = 0;
59 }
60 } else if(*p1 == CEND) {
61 if(!dolflag) {
62 if(ipc->negfl)
63 goto yes;
64 ipc++;
65 continue;
66 }
67
68 } else if(*p1 == CLNUM) {
69 c = p1[1];
70 if(lnum != tlno[c]) {
71 if(ipc->negfl)
72 goto yes;
73 ipc++;
74 continue;
75 }
76 if(p2)
77 ipc->inar = 1;
78 } else if(match(p1, 0)) {
79 if(p2)
80 ipc->inar = 1;
81 } else {
82 if(ipc->negfl)
83 goto yes;
84 ipc++;
85 continue;
86 }
87 }
88
89 if(ipc->negfl) {
90 ipc++;
91 continue;
92 }
93 yes:
94 command(ipc);
95
96 if(delflag)
97 break;
98
99 if(jflag) {
100 jflag = 0;
101 if((ipc = ipc->lb1) == 0) {
102 ipc = ptrspace;
103 break;
104 }
105 } else
106 ipc++;
107
108 }
109 if(!nflag && !delflag) {
110 for(p1 = linebuf; p1 < spend; p1++)
111 putc(*p1, stdout);
112 putc('\n', stdout);
113 }
114
115 if(aptr > abuf) {
116 arout();
117 }
118
119 delflag = 0;
120
121 }
122}
123match(expbuf, gf)
124char *expbuf;
125{
126 register char *p1, *p2, c;
127
128 if(gf) {
129 if(*expbuf) return(0);
130 p1 = linebuf;
131 p2 = genbuf;
132 while(*p1++ = *p2++);
133 locs = p1 = loc2;
134 } else {
135 p1 = linebuf;
136 locs = 0;
137 }
138
139 p2 = expbuf;
140 if(*p2++) {
141 loc1 = p1;
142 if(*p2 == CCHR && p2[1] != *p1)
143 return(0);
144 return(advance(p1, p2));
145 }
146
147 /* fast check for first character */
148
149 if(*p2 == CCHR) {
150 c = p2[1];
151 do {
152 if(*p1 != c)
153 continue;
154 if(advance(p1, p2)) {
155 loc1 = p1;
156 return(1);
157 }
158 } while(*p1++);
159 return(0);
160 }
161
162 do {
163 if(advance(p1, p2)) {
164 loc1 = p1;
165 return(1);
166 }
167 } while(*p1++);
168 return(0);
169}
170advance(alp, aep)
171char *alp, *aep;
172{
173 register char *lp, *ep, *curlp;
174 char c;
175 char *bbeg;
176 int ct;
177
178/*fprintf(stderr, "*lp = %c, %o\n*ep = %c, %o\n", *lp, *lp, *ep, *ep); /*DEBUG*/
179
180 lp = alp;
181 ep = aep;
182 for (;;) switch (*ep++) {
183
184 case CCHR:
185 if (*ep++ == *lp++)
186 continue;
187 return(0);
188
189 case CDOT:
190 if (*lp++)
191 continue;
192 return(0);
193
194 case CNL:
195 case CDOL:
196 if (*lp == 0)
197 continue;
198 return(0);
199
200 case CEOF:
201 loc2 = lp;
202 return(1);
203
204 case CCL:
205 c = *lp++ & 0177;
206 if(ep[c>>3] & bittab[c & 07]) {
207 ep += 16;
208 continue;
209 }
210 return(0);
211
212 case CBRA:
213 braslist[*ep++] = lp;
214 continue;
215
216 case CKET:
217 braelist[*ep++] = lp;
218 continue;
219
220 case CBACK:
221 bbeg = braslist[*ep];
222 ct = braelist[*ep++] - bbeg;
223
224 if(ecmp(bbeg, lp, ct)) {
225 lp += ct;
226 continue;
227 }
228 return(0);
229
230 case CBACK|STAR:
231 bbeg = braslist[*ep];
232 ct = braelist[*ep++] - bbeg;
233 curlp = lp;
234 while(ecmp(bbeg, lp, ct))
235 lp += ct;
236
237 while(lp >= curlp) {
238 if(advance(lp, ep)) return(1);
239 lp -= ct;
240 }
241 return(0);
242
243
244 case CDOT|STAR:
245 curlp = lp;
246 while (*lp++);
247 goto star;
248
249 case CCHR|STAR:
250 curlp = lp;
251 while (*lp++ == *ep);
252 ep++;
253 goto star;
254
255 case CCL|STAR:
256 curlp = lp;
257 do {
258 c = *lp++ & 0177;
259 } while(ep[c>>3] & bittab[c & 07]);
260 ep += 16;
261 goto star;
262
263 star:
264 if(--lp == curlp) {
265 continue;
266 }
267
268 if(*ep == CCHR) {
269 c = ep[1];
270 do {
271 if(*lp != c)
272 continue;
273 if(advance(lp, ep))
274 return(1);
275 } while(lp-- > curlp);
276 return(0);
277 }
278
279 if(*ep == CBACK) {
280 c = *(braslist[ep[1]]);
281 do {
282 if(*lp != c)
283 continue;
284 if(advance(lp, ep))
285 return(1);
286 } while(lp-- > curlp);
287 return(0);
288 }
289
290 do {
291 if(lp == locs) break;
292 if (advance(lp, ep))
293 return(1);
294 } while (lp-- > curlp);
295 return(0);
296
297 default:
298 fprintf(stderr, "RE botch, %o\n", *--ep);
299 }
300}
301substitute(ipc)
302union reptr *ipc;
303{
304 if(match(ipc->re1, 0) == 0) return(0);
305
306 sflag = 1;
307 dosub(ipc->rhs);
308
309 if(ipc->gfl) {
310 while(*loc2) {
311 if(match(ipc->re1, 1) == 0) break;
312 dosub(ipc->rhs);
313 }
314 }
315 return(1);
316}
317
318dosub(rhsbuf)
319char *rhsbuf;
320{
321 register char *lp, *sp, *rp;
322 int c;
323
324 lp = linebuf;
325 sp = genbuf;
326 rp = rhsbuf;
327 while (lp < loc1)
328 *sp++ = *lp++;
329 while(c = *rp++) {
330 if (c == '&') {
331 sp = place(sp, loc1, loc2);
332 continue;
333 } else if (c&0200 && (c &= 0177) >= '1' && c < NBRA+'1') {
334 sp = place(sp, braslist[c-'1'], braelist[c-'1']);
335 continue;
336 }
337 *sp++ = c&0177;
338 if (sp >= &genbuf[LBSIZE])
339 fprintf(stderr, "output line too long.\n");
340 }
341 lp = loc2;
342 loc2 = sp - genbuf + linebuf;
343 while (*sp++ = *lp++)
344 if (sp >= &genbuf[LBSIZE]) {
345 fprintf(stderr, "Output line too long.\n");
346 }
347 lp = linebuf;
348 sp = genbuf;
349 while (*lp++ = *sp++);
350 spend = lp-1;
351}
352char *place(asp, al1, al2)
353char *asp, *al1, *al2;
354{
355 register char *sp, *l1, *l2;
356
357 sp = asp;
358 l1 = al1;
359 l2 = al2;
360 while (l1 < l2) {
361 *sp++ = *l1++;
362 if (sp >= &genbuf[LBSIZE])
363 fprintf(stderr, "Output line too long.\n");
364 }
365 return(sp);
366}
367
368command(ipc)
369union reptr *ipc;
370{
371 register int i;
372 register char *p1, *p2;
373 char *execp;
374
375
376 switch(ipc->command) {
377
378 case ACOM:
379 *aptr++ = ipc;
380 if(aptr >= &abuf[ABUFSIZE]) {
381 fprintf(stderr, "Too many appends after line %ld\n",
382 lnum);
383 }
384 *aptr = 0;
385 break;
386
387 case CCOM:
388 delflag = 1;
389 if(!ipc->inar || dolflag) {
390 for(p1 = ipc->re1; *p1; )
391 putc(*p1++, stdout);
392 putc('\n', stdout);
393 }
394 break;
395 case DCOM:
396 delflag++;
397 break;
398 case CDCOM:
399 p1 = p2 = linebuf;
400
401 while(*p1 != '\n') {
402 if(*p1++ == 0) {
403 delflag++;
404 return;
405 }
406 }
407
408 p1++;
409 while(*p2++ = *p1++);
410 spend = p2-1;
411 jflag++;
412 break;
413
414 case EQCOM:
415 fprintf(stdout, "%ld\n", lnum);
416 break;
417
418 case GCOM:
419 p1 = linebuf;
420 p2 = holdsp;
421 while(*p1++ = *p2++);
422 spend = p1-1;
423 break;
424
425 case CGCOM:
426 *spend++ = '\n';
427 p1 = spend;
428 p2 = holdsp;
429 while(*p1++ = *p2++);
430 spend = p1-1;
431 break;
432
433 case HCOM:
434 p1 = holdsp;
435 p2 = linebuf;
436 while(*p1++ = *p2++);
437 hspend = p1-1;
438 break;
439
440 case CHCOM:
441 *hspend++ = '\n';
442 p1 = hspend;
443 p2 = linebuf;
444 while(*p1++ = *p2++);
445 hspend = p1-1;
446 break;
447
448 case ICOM:
449 for(p1 = ipc->re1; *p1; )
450 putc(*p1++, stdout);
451 putc('\n', stdout);
452 break;
453
454 case BCOM:
455 jflag = 1;
456 break;
457
458 case LCOM:
459 break;
460
461 case NCOM:
462 if(!nflag) {
463 for(p1 = linebuf; p1 < spend; p1++)
464 putc(*p1, stdout);
465 putc('\n', stdout);
466 }
467
468 if(aptr > abuf)
469 arout();
470 if((execp = gline(linebuf)) == badp) {
471 pending = ipc;
472 delflag = 1;
473 break;
474 }
475 spend = execp;
476
477 break;
478 case CNCOM:
479 if(aptr > abuf)
480 arout();
481 *spend++ = '\n';
482 if((execp = gline(spend)) == badp) {
483 pending = ipc;
484 delflag = 1;
485 break;
486 }
487 spend = execp;
488 break;
489
490 case PCOM:
491 for(p1 = linebuf; p1 < spend; p1++)
492 putc(*p1, stdout);
493 putc('\n', stdout);
494 break;
495 case CPCOM:
496 cpcom:
497 for(p1 = linebuf; *p1 != '\n' && *p1 != '\0'; )
498 putc(*p1++, stdout);
499 putc('\n', stdout);
500 break;
501
502 case QCOM:
503 if(!nflag) {
504 for(p1 = linebuf; p1 < spend; p1++)
505 putc(*p1, stdout);
506 putc('\n', stdout);
507 }
508 if(aptr > abuf) arout();
509 fclose(stdout);
510 exit(0);
511 case RCOM:
512
513 *aptr++ = ipc;
514 if(aptr >= &abuf[ABUFSIZE])
515 fprintf(stderr, "Too many reads after line%ld\n",
516 lnum);
517
518 *aptr = 0;
519
520 break;
521
522 case SCOM:
523 i = substitute(ipc);
524 if(ipc->pfl && nflag && i)
525 if(ipc->pfl == 1) {
526 for(p1 = linebuf; p1 < spend; p1++)
527 putc(*p1, stdout);
528 putc('\n', stdout);
529 }
530 else
531 goto cpcom;
532 if(i && ipc->fcode)
533 goto wcom;
534 break;
535
536 case TCOM:
537 if(sflag == 0) break;
538 sflag = 0;
539 jflag = 1;
540 break;
541
542 wcom:
543 case WCOM:
544 fprintf(ipc->fcode, "%s\n", linebuf);
545 break;
546 case XCOM:
547 p1 = linebuf;
548 p2 = genbuf;
549 while(*p2++ = *p1++);
550 p1 = holdsp;
551 p2 = linebuf;
552 while(*p2++ = *p1++);
553 spend = p2 - 1;
554 p1 = genbuf;
555 p2 = holdsp;
556 while(*p2++ = *p1++);
557 hspend = p2 - 1;
558 break;
559
560 case YCOM:
561 p1 = linebuf;
562 p2 = ipc->re1;
563 while(*p1 = p2[*p1]) p1++;
564 break;
565 }
566
567}
568
569char *gline(addr)
570char *addr;
571{
572 register char *p1, *p2;
573 register c;
574 p1 = addr;
575 p2 = cbp;
576 for (;;) {
577 if (p2 >= ebp) {
578 if ((c = read(f, ibuf, 512)) <= 0) {
579 return(badp);
580 }
581 p2 = ibuf;
582 ebp = ibuf+c;
583 }
584 if ((c = *p2++) == '\n') {
585 if(p2 >= ebp) {
586 if((c = read(f, ibuf, 512)) <= 0) {
587 close(f);
588 if(eargc == 0)
589 dolflag = 1;
590 }
591
592 p2 = ibuf;
593 ebp = ibuf + c;
594 }
595 break;
596 }
597 if(c)
598 if(p1 < lbend)
599 *p1++ = c;
600 }
601 lnum++;
602 *p1 = 0;
603 cbp = p2;
604
605 return(p1);
606}
607ecmp(a, b, count)
608char *a, *b;
609{
610 while(count--)
611 if(*a++ != *b++) return(0);
612 return(1);
613}
614
615arout()
616{
617 register char *p1;
618 FILE *fi;
619 char c;
620 int t;
621
622 aptr = abuf - 1;
623 while(*++aptr) {
624 if((*aptr)->command == ACOM) {
625 for(p1 = (*aptr)->re1; *p1; )
626 putc(*p1++, stdout);
627 putc('\n', stdout);
628 } else {
629 if((fi = fopen((*aptr)->re1, "r")) == NULL)
630 continue;
631 while((t = getc(fi)) != EOF) {
632 c = t;
633 putc(c, stdout);
634 }
635 fclose(fi);
636 }
637 }
638 aptr = abuf;
639 *aptr = 0;
640}
641