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