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