Commit | Line | Data |
---|---|---|
a209ee10 | 1 | /* sed0.c 4.2 85/06/19 */ |
e90a6148 RC |
2 | |
3 | #include <stdio.h> | |
4 | #include "sed.h" | |
5 | ||
6 | struct label *labtab = ltab; | |
7 | char CGMES[] = "command garbled: %s\n"; | |
8 | char TMMES[] = "Too much text: %s\n"; | |
9 | char LTL[] = "Label too long: %s\n"; | |
10 | char AD0MES[] = "No addresses allowed: %s\n"; | |
11 | char AD1MES[] = "Only one address allowed: %s\n"; | |
12 | char bittab[] = { | |
13 | 1, | |
14 | 2, | |
15 | 4, | |
16 | 8, | |
17 | 16, | |
18 | 32, | |
19 | 64, | |
20 | 128 | |
21 | }; | |
22 | ||
23 | main(argc, argv) | |
24 | char *argv[]; | |
25 | { | |
26 | ||
27 | eargc = argc; | |
28 | eargv = argv; | |
29 | ||
30 | badp = &bad; | |
31 | aptr = abuf; | |
32 | lab = labtab + 1; /* 0 reserved for end-pointer */ | |
33 | rep = ptrspace; | |
34 | rep->ad1 = respace; | |
35 | lbend = &linebuf[LBSIZE]; | |
36 | hend = &holdsp[LBSIZE]; | |
37 | lcomend = &genbuf[71]; | |
38 | ptrend = &ptrspace[PTRSIZE]; | |
39 | reend = &respace[RESIZE]; | |
40 | labend = &labtab[LABSIZE]; | |
41 | lnum = 0; | |
42 | pending = 0; | |
43 | depth = 0; | |
44 | spend = linebuf; | |
45 | hspend = holdsp; | |
46 | fcode[0] = stdout; | |
47 | nfiles = 1; | |
48 | ||
49 | if(eargc == 1) | |
50 | exit(0); | |
51 | ||
52 | ||
53 | while (--eargc > 0 && (++eargv)[0][0] == '-') | |
54 | switch (eargv[0][1]) { | |
55 | ||
56 | case 'n': | |
57 | nflag++; | |
58 | continue; | |
59 | ||
60 | case 'f': | |
61 | if(eargc-- <= 0) exit(2); | |
62 | ||
63 | if((fin = fopen(*++eargv, "r")) == NULL) { | |
64 | fprintf(stderr, "Cannot open pattern-file: %s\n", *eargv); | |
65 | exit(2); | |
66 | } | |
67 | ||
68 | fcomp(); | |
69 | fclose(fin); | |
70 | continue; | |
71 | ||
72 | case 'e': | |
73 | eflag++; | |
74 | fcomp(); | |
75 | eflag = 0; | |
76 | continue; | |
77 | ||
78 | case 'g': | |
79 | gflag++; | |
80 | continue; | |
81 | ||
82 | default: | |
83 | fprintf(stdout, "Unknown flag: %c\n", eargv[0][1]); | |
84 | continue; | |
85 | } | |
86 | ||
87 | ||
88 | if(compfl == 0) { | |
89 | eargv--; | |
90 | eargc++; | |
91 | eflag++; | |
92 | fcomp(); | |
93 | eargv++; | |
94 | eargc--; | |
95 | eflag = 0; | |
96 | } | |
97 | ||
98 | if(depth) { | |
99 | fprintf(stderr, "Too many {'s"); | |
100 | exit(2); | |
101 | } | |
102 | ||
103 | labtab->address = rep; | |
104 | ||
105 | dechain(); | |
106 | ||
107 | /* abort(); /*DEBUG*/ | |
108 | ||
109 | if(eargc <= 0) | |
110 | execute((char *)NULL); | |
111 | else while(--eargc >= 0) { | |
112 | execute(*eargv++); | |
113 | } | |
114 | fclose(stdout); | |
115 | exit(0); | |
116 | } | |
117 | fcomp() | |
118 | { | |
119 | ||
120 | register char *p, *op, *tp; | |
121 | char *address(); | |
122 | union reptr *pt, *pt1; | |
123 | int i; | |
124 | struct label *lpt; | |
125 | ||
126 | compfl = 1; | |
127 | op = lastre; | |
128 | ||
129 | if(rline(linebuf) < 0) return; | |
130 | if(*linebuf == '#') { | |
131 | if(linebuf[1] == 'n') | |
132 | nflag = 1; | |
133 | } | |
134 | else { | |
135 | cp = linebuf; | |
136 | goto comploop; | |
137 | } | |
138 | ||
139 | for(;;) { | |
140 | if(rline(linebuf) < 0) break; | |
141 | ||
142 | cp = linebuf; | |
143 | ||
144 | comploop: | |
145 | /* fprintf(stdout, "cp: %s\n", cp); /*DEBUG*/ | |
146 | while(*cp == ' ' || *cp == '\t') cp++; | |
147 | if(*cp == '\0' || *cp == '#') continue; | |
148 | if(*cp == ';') { | |
149 | cp++; | |
150 | goto comploop; | |
151 | } | |
152 | ||
153 | p = address(rep->ad1); | |
154 | if(p == badp) { | |
155 | fprintf(stderr, CGMES, linebuf); | |
156 | exit(2); | |
157 | } | |
158 | ||
159 | if(p == rep->ad1) { | |
160 | if(op) | |
161 | rep->ad1 = op; | |
162 | else { | |
163 | fprintf(stderr, "First RE may not be null\n"); | |
164 | exit(2); | |
165 | } | |
166 | } else if(p == 0) { | |
167 | p = rep->ad1; | |
168 | rep->ad1 = 0; | |
169 | } else { | |
170 | op = rep->ad1; | |
171 | if(*cp == ',' || *cp == ';') { | |
172 | cp++; | |
173 | if((rep->ad2 = p) > reend) { | |
174 | fprintf(stderr, TMMES, linebuf); | |
175 | exit(2); | |
176 | } | |
177 | p = address(rep->ad2); | |
178 | if(p == badp || p == 0) { | |
179 | fprintf(stderr, CGMES, linebuf); | |
180 | exit(2); | |
181 | } | |
182 | if(p == rep->ad2) | |
183 | rep->ad2 = op; | |
184 | else | |
185 | op = rep->ad2; | |
186 | ||
187 | } else | |
188 | rep->ad2 = 0; | |
189 | } | |
190 | ||
191 | if(p > reend) { | |
192 | fprintf(stderr, "Too much text: %s\n", linebuf); | |
193 | exit(2); | |
194 | } | |
195 | ||
196 | while(*cp == ' ' || *cp == '\t') cp++; | |
197 | ||
198 | swit: | |
199 | switch(*cp++) { | |
200 | ||
201 | default: | |
202 | fprintf(stderr, "Unrecognized command: %s\n", linebuf); | |
203 | exit(2); | |
204 | ||
205 | case '!': | |
206 | rep->negfl = 1; | |
207 | goto swit; | |
208 | ||
209 | case '{': | |
210 | rep->command = BCOM; | |
211 | rep->negfl = !(rep->negfl); | |
212 | cmpend[depth++] = &rep->lb1; | |
213 | if(++rep >= ptrend) { | |
214 | fprintf(stderr, "Too many commands: %s\n", linebuf); | |
215 | exit(2); | |
216 | } | |
217 | rep->ad1 = p; | |
218 | if(*cp == '\0') continue; | |
219 | ||
220 | goto comploop; | |
221 | ||
222 | case '}': | |
223 | if(rep->ad1) { | |
224 | fprintf(stderr, AD0MES, linebuf); | |
225 | exit(2); | |
226 | } | |
227 | ||
228 | if(--depth < 0) { | |
229 | fprintf(stderr, "Too many }'s\n"); | |
230 | exit(2); | |
231 | } | |
232 | *cmpend[depth] = rep; | |
233 | ||
234 | rep->ad1 = p; | |
235 | continue; | |
236 | ||
237 | case '=': | |
238 | rep->command = EQCOM; | |
239 | if(rep->ad2) { | |
240 | fprintf(stderr, AD1MES, linebuf); | |
241 | exit(2); | |
242 | } | |
243 | break; | |
244 | ||
245 | case ':': | |
246 | if(rep->ad1) { | |
247 | fprintf(stderr, AD0MES, linebuf); | |
248 | exit(2); | |
249 | } | |
250 | ||
251 | while(*cp++ == ' '); | |
252 | cp--; | |
253 | ||
254 | ||
255 | tp = lab->asc; | |
256 | while((*tp++ = *cp++)) | |
257 | if(tp >= &(lab->asc[8])) { | |
258 | fprintf(stderr, LTL, linebuf); | |
259 | exit(2); | |
260 | } | |
261 | *--tp = '\0'; | |
262 | ||
263 | if(lpt = search(lab)) { | |
264 | if(lpt->address) { | |
265 | fprintf(stderr, "Duplicate labels: %s\n", linebuf); | |
266 | exit(2); | |
267 | } | |
268 | } else { | |
269 | lab->chain = 0; | |
270 | lpt = lab; | |
271 | if(++lab >= labend) { | |
272 | fprintf(stderr, "Too many labels: %s\n", linebuf); | |
273 | exit(2); | |
274 | } | |
275 | } | |
276 | lpt->address = rep; | |
277 | rep->ad1 = p; | |
278 | ||
279 | continue; | |
280 | ||
281 | case 'a': | |
282 | rep->command = ACOM; | |
283 | if(rep->ad2) { | |
284 | fprintf(stderr, AD1MES, linebuf); | |
285 | exit(2); | |
286 | } | |
287 | if(*cp == '\\') cp++; | |
288 | if(*cp++ != '\n') { | |
289 | fprintf(stderr, CGMES, linebuf); | |
290 | exit(2); | |
291 | } | |
292 | rep->re1 = p; | |
293 | p = text(rep->re1); | |
294 | break; | |
295 | case 'c': | |
296 | rep->command = CCOM; | |
297 | if(*cp == '\\') cp++; | |
298 | if(*cp++ != ('\n')) { | |
299 | fprintf(stderr, CGMES, linebuf); | |
300 | exit(2); | |
301 | } | |
302 | rep->re1 = p; | |
303 | p = text(rep->re1); | |
304 | break; | |
305 | case 'i': | |
306 | rep->command = ICOM; | |
307 | if(rep->ad2) { | |
308 | fprintf(stderr, AD1MES, linebuf); | |
309 | exit(2); | |
310 | } | |
311 | if(*cp == '\\') cp++; | |
312 | if(*cp++ != ('\n')) { | |
313 | fprintf(stderr, CGMES, linebuf); | |
314 | exit(2); | |
315 | } | |
316 | rep->re1 = p; | |
317 | p = text(rep->re1); | |
318 | break; | |
319 | ||
320 | case 'g': | |
321 | rep->command = GCOM; | |
322 | break; | |
323 | ||
324 | case 'G': | |
325 | rep->command = CGCOM; | |
326 | break; | |
327 | ||
328 | case 'h': | |
329 | rep->command = HCOM; | |
330 | break; | |
331 | ||
332 | case 'H': | |
333 | rep->command = CHCOM; | |
334 | break; | |
335 | ||
336 | case 't': | |
337 | rep->command = TCOM; | |
338 | goto jtcommon; | |
339 | ||
340 | case 'b': | |
341 | rep->command = BCOM; | |
342 | jtcommon: | |
343 | while(*cp++ == ' '); | |
344 | cp--; | |
345 | ||
346 | if(*cp == '\0') { | |
347 | if(pt = labtab->chain) { | |
348 | while(pt1 = pt->lb1) | |
349 | pt = pt1; | |
350 | pt->lb1 = rep; | |
351 | } else | |
352 | labtab->chain = rep; | |
353 | break; | |
354 | } | |
355 | tp = lab->asc; | |
356 | while((*tp++ = *cp++)) | |
357 | if(tp >= &(lab->asc[8])) { | |
358 | fprintf(stderr, LTL, linebuf); | |
359 | exit(2); | |
360 | } | |
361 | cp--; | |
362 | *--tp = '\0'; | |
363 | ||
364 | if(lpt = search(lab)) { | |
365 | if(lpt->address) { | |
366 | rep->lb1 = lpt->address; | |
367 | } else { | |
368 | pt = lpt->chain; | |
369 | while(pt1 = pt->lb1) | |
370 | pt = pt1; | |
371 | pt->lb1 = rep; | |
372 | } | |
373 | } else { | |
374 | lab->chain = rep; | |
375 | lab->address = 0; | |
376 | if(++lab >= labend) { | |
377 | fprintf(stderr, "Too many labels: %s\n", linebuf); | |
378 | exit(2); | |
379 | } | |
380 | } | |
381 | break; | |
382 | ||
383 | case 'n': | |
384 | rep->command = NCOM; | |
385 | break; | |
386 | ||
387 | case 'N': | |
388 | rep->command = CNCOM; | |
389 | break; | |
390 | ||
391 | case 'p': | |
392 | rep->command = PCOM; | |
393 | break; | |
394 | ||
395 | case 'P': | |
396 | rep->command = CPCOM; | |
397 | break; | |
398 | ||
399 | case 'r': | |
400 | rep->command = RCOM; | |
401 | if(rep->ad2) { | |
402 | fprintf(stderr, AD1MES, linebuf); | |
403 | exit(2); | |
404 | } | |
405 | if(*cp++ != ' ') { | |
406 | fprintf(stderr, CGMES, linebuf); | |
407 | exit(2); | |
408 | } | |
409 | rep->re1 = p; | |
410 | p = text(rep->re1); | |
411 | break; | |
412 | ||
413 | case 'd': | |
414 | rep->command = DCOM; | |
415 | break; | |
416 | ||
417 | case 'D': | |
418 | rep->command = CDCOM; | |
419 | rep->lb1 = ptrspace; | |
420 | break; | |
421 | ||
422 | case 'q': | |
423 | rep->command = QCOM; | |
424 | if(rep->ad2) { | |
425 | fprintf(stderr, AD1MES, linebuf); | |
426 | exit(2); | |
427 | } | |
428 | break; | |
429 | ||
430 | case 'l': | |
431 | rep->command = LCOM; | |
432 | break; | |
433 | ||
434 | case 's': | |
435 | rep->command = SCOM; | |
436 | seof = *cp++; | |
437 | rep->re1 = p; | |
438 | p = compile(rep->re1); | |
439 | if(p == badp) { | |
440 | fprintf(stderr, CGMES, linebuf); | |
441 | exit(2); | |
442 | } | |
443 | if(p == rep->re1) { | |
a209ee10 JB |
444 | if(op) |
445 | rep->re1 = op; | |
446 | else { | |
447 | fprintf(stderr, | |
448 | "First RE may not be null\n"); | |
449 | exit(2); | |
450 | } | |
e90a6148 RC |
451 | } else { |
452 | op = rep->re1; | |
453 | } | |
454 | ||
455 | if((rep->rhs = p) > reend) { | |
456 | fprintf(stderr, TMMES, linebuf); | |
457 | exit(2); | |
458 | } | |
459 | ||
460 | if((p = compsub(rep->rhs)) == badp) { | |
461 | fprintf(stderr, CGMES, linebuf); | |
462 | exit(2); | |
463 | } | |
464 | if(*cp == 'g') { | |
465 | cp++; | |
466 | rep->gfl++; | |
467 | } else if(gflag) | |
468 | rep->gfl++; | |
469 | ||
470 | if(*cp == 'p') { | |
471 | cp++; | |
472 | rep->pfl = 1; | |
473 | } | |
474 | ||
475 | if(*cp == 'P') { | |
476 | cp++; | |
477 | rep->pfl = 2; | |
478 | } | |
479 | ||
480 | if(*cp == 'w') { | |
481 | cp++; | |
482 | if(*cp++ != ' ') { | |
483 | fprintf(stderr, CGMES, linebuf); | |
484 | exit(2); | |
485 | } | |
486 | if(nfiles >= 10) { | |
487 | fprintf(stderr, "Too many files in w commands\n"); | |
488 | exit(2); | |
489 | } | |
490 | ||
491 | text(fname[nfiles]); | |
492 | for(i = nfiles - 1; i >= 0; i--) | |
493 | if(cmp(fname[nfiles],fname[i]) == 0) { | |
494 | rep->fcode = fcode[i]; | |
495 | goto done; | |
496 | } | |
497 | if((rep->fcode = fopen(fname[nfiles], "w")) == NULL) { | |
498 | fprintf(stderr, "cannot open %s\n", fname[nfiles]); | |
499 | exit(2); | |
500 | } | |
501 | fcode[nfiles++] = rep->fcode; | |
502 | } | |
503 | break; | |
504 | ||
505 | case 'w': | |
506 | rep->command = WCOM; | |
507 | if(*cp++ != ' ') { | |
508 | fprintf(stderr, CGMES, linebuf); | |
509 | exit(2); | |
510 | } | |
511 | if(nfiles >= 10){ | |
512 | fprintf(stderr, "Too many files in w commands\n"); | |
513 | exit(2); | |
514 | } | |
515 | ||
516 | text(fname[nfiles]); | |
517 | for(i = nfiles - 1; i >= 0; i--) | |
518 | if(cmp(fname[nfiles], fname[i]) == 0) { | |
519 | rep->fcode = fcode[i]; | |
520 | goto done; | |
521 | } | |
522 | ||
523 | if((rep->fcode = fopen(fname[nfiles], "w")) == NULL) { | |
524 | fprintf(stderr, "Cannot create %s\n", fname[nfiles]); | |
525 | exit(2); | |
526 | } | |
527 | fcode[nfiles++] = rep->fcode; | |
528 | break; | |
529 | ||
530 | case 'x': | |
531 | rep->command = XCOM; | |
532 | break; | |
533 | ||
534 | case 'y': | |
535 | rep->command = YCOM; | |
536 | seof = *cp++; | |
537 | rep->re1 = p; | |
538 | p = ycomp(rep->re1); | |
539 | if(p == badp) { | |
540 | fprintf(stderr, CGMES, linebuf); | |
541 | exit(2); | |
542 | } | |
543 | if(p > reend) { | |
544 | fprintf(stderr, TMMES, linebuf); | |
545 | exit(2); | |
546 | } | |
547 | break; | |
548 | ||
549 | } | |
550 | done: | |
551 | if(++rep >= ptrend) { | |
552 | fprintf(stderr, "Too many commands, last: %s\n", linebuf); | |
553 | exit(2); | |
554 | } | |
555 | ||
556 | rep->ad1 = p; | |
557 | ||
558 | if(*cp++ != '\0') { | |
559 | if(cp[-1] == ';') | |
560 | goto comploop; | |
561 | fprintf(stderr, CGMES, linebuf); | |
562 | exit(2); | |
563 | } | |
564 | ||
565 | } | |
566 | rep->command = 0; | |
567 | lastre = op; | |
568 | } | |
569 | char *compsub(rhsbuf) | |
570 | char *rhsbuf; | |
571 | { | |
572 | register char *p, *q; | |
573 | ||
574 | p = rhsbuf; | |
575 | q = cp; | |
576 | for(;;) { | |
577 | if((*p = *q++) == '\\') { | |
578 | *p = *q++; | |
579 | if(*p > numbra + '0' && *p <= '9') | |
580 | return(badp); | |
581 | *p++ |= 0200; | |
582 | continue; | |
583 | } | |
584 | if(*p == seof) { | |
585 | *p++ = '\0'; | |
586 | cp = q; | |
587 | return(p); | |
588 | } | |
589 | if(*p++ == '\0') { | |
590 | return(badp); | |
591 | } | |
592 | ||
593 | } | |
594 | } | |
595 | ||
596 | char *compile(expbuf) | |
597 | char *expbuf; | |
598 | { | |
599 | register c; | |
600 | register char *ep, *sp; | |
601 | char neg; | |
602 | char *lastep, *cstart; | |
603 | int cclcnt; | |
604 | int closed; | |
605 | char bracket[NBRA], *bracketp; | |
606 | ||
607 | if(*cp == seof) { | |
608 | cp++; | |
609 | return(expbuf); | |
610 | } | |
611 | ||
612 | ep = expbuf; | |
613 | lastep = 0; | |
614 | bracketp = bracket; | |
615 | closed = numbra = 0; | |
616 | sp = cp; | |
617 | if (*sp == '^') { | |
618 | *ep++ = 1; | |
619 | sp++; | |
620 | } else { | |
621 | *ep++ = 0; | |
622 | } | |
623 | for (;;) { | |
624 | if (ep >= &expbuf[ESIZE]) { | |
625 | cp = sp; | |
626 | return(badp); | |
627 | } | |
628 | if((c = *sp++) == seof) { | |
629 | if(bracketp != bracket) { | |
630 | cp = sp; | |
631 | return(badp); | |
632 | } | |
633 | cp = sp; | |
634 | *ep++ = CEOF; | |
635 | return(ep); | |
636 | } | |
637 | if(c != '*') | |
638 | lastep = ep; | |
639 | switch (c) { | |
640 | ||
641 | case '\\': | |
642 | if((c = *sp++) == '(') { | |
643 | if(numbra >= NBRA) { | |
644 | cp = sp; | |
645 | return(badp); | |
646 | } | |
647 | *bracketp++ = numbra; | |
648 | *ep++ = CBRA; | |
649 | *ep++ = numbra++; | |
650 | continue; | |
651 | } | |
652 | if(c == ')') { | |
653 | if(bracketp <= bracket) { | |
654 | cp = sp; | |
655 | return(badp); | |
656 | } | |
657 | *ep++ = CKET; | |
658 | *ep++ = *--bracketp; | |
659 | closed++; | |
660 | continue; | |
661 | } | |
662 | ||
663 | if(c >= '1' && c <= '9') { | |
664 | if((c -= '1') >= closed) | |
665 | return(badp); | |
666 | ||
667 | *ep++ = CBACK; | |
668 | *ep++ = c; | |
669 | continue; | |
670 | } | |
671 | if(c == '\n') { | |
672 | cp = sp; | |
673 | return(badp); | |
674 | } | |
675 | if(c == 'n') { | |
676 | c = '\n'; | |
677 | } | |
678 | goto defchar; | |
679 | ||
680 | case '\0': | |
681 | continue; | |
682 | case '\n': | |
683 | cp = sp; | |
684 | return(badp); | |
685 | ||
686 | case '.': | |
687 | *ep++ = CDOT; | |
688 | continue; | |
689 | ||
690 | case '*': | |
691 | if (lastep == 0) | |
692 | goto defchar; | |
693 | if(*lastep == CKET) { | |
694 | cp = sp; | |
695 | return(badp); | |
696 | } | |
697 | *lastep |= STAR; | |
698 | continue; | |
699 | ||
700 | case '$': | |
701 | if (*sp != seof) | |
702 | goto defchar; | |
703 | *ep++ = CDOL; | |
704 | continue; | |
705 | ||
706 | case '[': | |
707 | if(&ep[17] >= &expbuf[ESIZE]) { | |
708 | fprintf(stderr, "RE too long: %s\n", linebuf); | |
709 | exit(2); | |
710 | } | |
711 | ||
712 | *ep++ = CCL; | |
713 | ||
714 | neg = 0; | |
715 | if((c = *sp++) == '^') { | |
716 | neg = 1; | |
717 | c = *sp++; | |
718 | } | |
719 | ||
720 | cstart = sp; | |
721 | do { | |
722 | if(c == '\0') { | |
723 | fprintf(stderr, CGMES, linebuf); | |
724 | exit(2); | |
725 | } | |
726 | if (c=='-' && sp>cstart && *sp!=']') { | |
727 | for (c = sp[-2]; c<*sp; c++) | |
728 | ep[c>>3] |= bittab[c&07]; | |
729 | } | |
730 | if(c == '\\') { | |
731 | switch(c = *sp++) { | |
732 | case 'n': | |
733 | c = '\n'; | |
734 | break; | |
735 | } | |
736 | } | |
737 | ||
738 | ep[c >> 3] |= bittab[c & 07]; | |
739 | } while((c = *sp++) != ']'); | |
740 | ||
741 | if(neg) | |
742 | for(cclcnt = 0; cclcnt < 16; cclcnt++) | |
743 | ep[cclcnt] ^= -1; | |
744 | ep[0] &= 0376; | |
745 | ||
746 | ep += 16; | |
747 | ||
748 | continue; | |
749 | ||
750 | defchar: | |
751 | default: | |
752 | *ep++ = CCHR; | |
753 | *ep++ = c; | |
754 | } | |
755 | } | |
756 | } | |
757 | rline(lbuf) | |
758 | char *lbuf; | |
759 | { | |
760 | register char *p, *q; | |
761 | register t; | |
762 | static char *saveq; | |
763 | ||
764 | p = lbuf - 1; | |
765 | ||
766 | if(eflag) { | |
767 | if(eflag > 0) { | |
768 | eflag = -1; | |
769 | if(eargc-- <= 0) | |
770 | exit(2); | |
771 | q = *++eargv; | |
772 | while(*++p = *q++) { | |
773 | if(*p == '\\') { | |
774 | if((*++p = *q++) == '\0') { | |
775 | saveq = 0; | |
776 | return(-1); | |
777 | } else | |
778 | continue; | |
779 | } | |
780 | if(*p == '\n') { | |
781 | *p = '\0'; | |
782 | saveq = q; | |
783 | return(1); | |
784 | } | |
785 | } | |
786 | saveq = 0; | |
787 | return(1); | |
788 | } | |
789 | if((q = saveq) == 0) return(-1); | |
790 | ||
791 | while(*++p = *q++) { | |
792 | if(*p == '\\') { | |
793 | if((*++p = *q++) == '0') { | |
794 | saveq = 0; | |
795 | return(-1); | |
796 | } else | |
797 | continue; | |
798 | } | |
799 | if(*p == '\n') { | |
800 | *p = '\0'; | |
801 | saveq = q; | |
802 | return(1); | |
803 | } | |
804 | } | |
805 | saveq = 0; | |
806 | return(1); | |
807 | } | |
808 | ||
809 | while((t = getc(fin)) != EOF) { | |
810 | *++p = t; | |
811 | if(*p == '\\') { | |
812 | t = getc(fin); | |
813 | *++p = t; | |
814 | } | |
815 | else if(*p == '\n') { | |
816 | *p = '\0'; | |
817 | return(1); | |
818 | } | |
819 | } | |
820 | *++p = '\0'; | |
821 | return(-1); | |
822 | } | |
823 | ||
824 | char *address(expbuf) | |
825 | char *expbuf; | |
826 | { | |
827 | register char *rcp; | |
828 | long lno; | |
829 | ||
830 | if(*cp == '$') { | |
831 | cp++; | |
832 | *expbuf++ = CEND; | |
833 | *expbuf++ = CEOF; | |
834 | return(expbuf); | |
835 | } | |
836 | ||
837 | if(*cp == '/') { | |
838 | seof = '/'; | |
839 | cp++; | |
840 | return(compile(expbuf)); | |
841 | } | |
842 | ||
843 | rcp = cp; | |
844 | lno = 0; | |
845 | ||
846 | while(*rcp >= '0' && *rcp <= '9') | |
847 | lno = lno*10 + *rcp++ - '0'; | |
848 | ||
849 | if(rcp > cp) { | |
850 | *expbuf++ = CLNUM; | |
851 | *expbuf++ = nlno; | |
852 | tlno[nlno++] = lno; | |
853 | if(nlno >= NLINES) { | |
854 | fprintf(stderr, "Too many line numbers\n"); | |
855 | exit(2); | |
856 | } | |
857 | *expbuf++ = CEOF; | |
858 | cp = rcp; | |
859 | return(expbuf); | |
860 | } | |
861 | return(0); | |
862 | } | |
863 | cmp(a, b) | |
864 | char *a,*b; | |
865 | { | |
866 | register char *ra, *rb; | |
867 | ||
868 | ra = a - 1; | |
869 | rb = b - 1; | |
870 | ||
871 | while(*++ra == *++rb) | |
872 | if(*ra == '\0') return(0); | |
873 | return(1); | |
874 | } | |
875 | ||
876 | char *text(textbuf) | |
877 | char *textbuf; | |
878 | { | |
879 | register char *p, *q; | |
880 | ||
881 | p = textbuf; | |
882 | q = cp; | |
883 | while(*q == '\t' || *q == ' ') q++; | |
884 | for(;;) { | |
885 | ||
886 | if((*p = *q++) == '\\') | |
887 | *p = *q++; | |
888 | if(*p == '\0') { | |
889 | cp = --q; | |
890 | return(++p); | |
891 | } | |
892 | if(*p == '\n') { | |
893 | while(*q == '\t' || *q == ' ') q++; | |
894 | } | |
895 | p++; | |
896 | } | |
897 | } | |
898 | ||
899 | ||
900 | struct label *search(ptr) | |
901 | struct label *ptr; | |
902 | { | |
903 | struct label *rp; | |
904 | ||
905 | rp = labtab; | |
906 | while(rp < ptr) { | |
907 | if(cmp(rp->asc, ptr->asc) == 0) | |
908 | return(rp); | |
909 | rp++; | |
910 | } | |
911 | ||
912 | return(0); | |
913 | } | |
914 | ||
915 | ||
916 | dechain() | |
917 | { | |
918 | struct label *lptr; | |
919 | union reptr *rptr, *trptr; | |
920 | ||
921 | for(lptr = labtab; lptr < lab; lptr++) { | |
922 | ||
923 | if(lptr->address == 0) { | |
924 | fprintf(stderr, "Undefined label: %s\n", lptr->asc); | |
925 | exit(2); | |
926 | } | |
927 | ||
928 | if(lptr->chain) { | |
929 | rptr = lptr->chain; | |
930 | while(trptr = rptr->lb1) { | |
931 | rptr->lb1 = lptr->address; | |
932 | rptr = trptr; | |
933 | } | |
934 | rptr->lb1 = lptr->address; | |
935 | } | |
936 | } | |
937 | } | |
938 | ||
939 | char *ycomp(expbuf) | |
940 | char *expbuf; | |
941 | { | |
942 | register char c, *ep, *tsp; | |
943 | char *sp; | |
944 | ||
945 | ep = expbuf; | |
946 | sp = cp; | |
947 | for(tsp = cp; *tsp != seof; tsp++) { | |
948 | if(*tsp == '\\') | |
949 | tsp++; | |
950 | if(*tsp == '\n') | |
951 | return(badp); | |
952 | } | |
953 | tsp++; | |
954 | ||
955 | while((c = *sp++ & 0177) != seof) { | |
956 | if(c == '\\' && *sp == 'n') { | |
957 | sp++; | |
958 | c = '\n'; | |
959 | } | |
960 | if((ep[c] = *tsp++) == '\\' && *tsp == 'n') { | |
961 | ep[c] = '\n'; | |
962 | tsp++; | |
963 | } | |
964 | if(ep[c] == seof || ep[c] == '\0') | |
965 | return(badp); | |
966 | } | |
967 | if(*tsp != seof) | |
968 | return(badp); | |
969 | cp = ++tsp; | |
970 | ||
971 | for(c = 0; !(c & 0200); c++) | |
972 | if(ep[c] == 0) | |
973 | ep[c] = c; | |
974 | ||
975 | return(ep + 0200); | |
976 | } |