|
|
1.1 root 1: /*
2: * n1.c
3: *
4: * consume options, initialization, main loop,
5: * input routines, escape function calling
6: */
7:
8: #include <ctype.h>
9: #include <signal.h>
10: #include <sys/types.h>
11: #include <sys/stat.h>
12: #include <setjmp.h>
13:
14: #include "tdef.h"
15: #include "ext.h"
16:
17: #ifdef NROFF
18: #include "tw.h"
19: #endif
20:
21: jmp_buf sjbuf;
22: extern char *sprintf();
23: static char *sprintn();
24: static printn();
25: filep ipl[NSO];
26: long offl[NSO];
27: long ioff;
28: char cfname[NSO+1][NS] = { "<standard input>" }; /*file name stack*/
29: int cfline[NSO]; /*input line count stack*/
30: char *progname; /* program name (troff) */
31:
32: main(argc, argv)
33: int argc;
34: char **argv;
35: {
36: register char *p;
37: register j;
38: register tchar i;
39: extern catch(), kcatch();
40: char **oargv, *getenv();
41:
42: progname = argv[0];
43: signal(SIGHUP, catch);
44: if (signal(SIGINT, catch) == SIG_IGN) {
45: signal(SIGHUP, SIG_IGN);
46: signal(SIGINT, SIG_IGN);
47: signal(SIGQUIT, SIG_IGN);
48: }
49: signal(SIGPIPE, catch);
50: signal(SIGTERM, kcatch);
51: oargv = argv;
52: mrehash();
53: nrehash();
54: init0();
55:
56: #ifdef NROFF
57: if ((p = getenv("NROFFTERM")) != 0)
58: strcpy(devname, p);
59: #else
60: if ((p = getenv("TYPESETTER")) != 0)
61: strcpy(devname, p);
62: #endif
63:
64: while (--argc > 0 && (++argv)[0][0] == '-')
65: switch (argv[0][1]) {
66:
67: case 'F': /* switch font tables from default */
68: if (argv[0][2] != '\0') {
69: strcpy(termtab, &argv[0][2]);
70: strcpy(fontdir, &argv[0][2]);
71: } else {
72: argv++; argc--;
73: strcpy(termtab, argv[0]);
74: strcpy(fontdir, argv[0]);
75: }
76: continue;
77: case 0:
78: goto start;
79: case 'i':
80: stdi++;
81: continue;
82: case 'q':
83: #ifdef NROFF
84: quiet++;
85: save_tty();
86: #else
87: errprint("-q option ignored in troff");
88: #endif NROFF
89: continue;
90: case 'n':
91: npn = ctoi(&argv[0][2]);
92: continue;
93: case 'u': /* set emboldening amount */
94: bdtab[3] = ctoi(&argv[0][2]);
95: if (bdtab[3] < 0 || bdtab[3] > 50)
96: bdtab[3] = 0;
97: continue;
98: case 's':
99: if (!(stop = ctoi(&argv[0][2])))
100: stop++;
101: continue;
102: case 'r':
103: eibuf = sprintf(ibuf+strlen(ibuf), ".nr %c %s\n",
104: argv[0][2], &argv[0][3]);
105: continue;
106: case 'c':
107: case 'm':
108: if (mflg++ >= NMF) {
109: errprint("Too many macro packages: %s", argv[0]);
110: continue;
111: }
112: strcpy (mfiles[nmfi], nextf);
113: strcat (mfiles[nmfi++], &argv[0][2]);
114: continue;
115: case 'o':
116: getpn(&argv[0][2]);
117: continue;
118: case 'T':
119: strcpy(devname, &argv[0][2]);
120: dotT++;
121: continue;
122: #ifdef NROFF
123: case 'h':
124: hflg++;
125: continue;
126: case 'z':
127: no_out++;
128: continue;
129: case 'e':
130: eqflg++;
131: continue;
132: #endif
133: #ifndef NROFF
134: case 'z':
135: no_out++;
136: case 'a':
137: ascii = 1;
138: nofeed++;
139: continue;
140: case 'f':
141: nofeed++;
142: continue;
143: #endif
144: default:
145: errprint("unknown option %s", argv[0]);
146: done(02);
147: }
148:
149: start:
150: init1(oargv[0][0]);
151: argp = argv;
152: rargc = argc;
153: nmfi = 0;
154: init2();
155: setjmp(sjbuf);
156: loop:
157: copyf = lgf = nb = nflush = nlflg = 0;
158: if (ip && rbf0(ip) == 0 && ejf && frame->pframe <= ejl) {
159: nflush++;
160: trap = 0;
161: eject((struct s *)0);
162: goto loop;
163: }
164: i = getch();
165: if (pendt)
166: goto Lt;
167: if ((j = cbits(i)) == XPAR) {
168: copyf++;
169: tflg++;
170: while (cbits(i) != '\n')
171: pchar(i = getch());
172: tflg = 0;
173: copyf--;
174: goto loop;
175: }
176: if (j == cc || j == c2) {
177: if (j == c2)
178: nb++;
179: copyf++;
180: while ((j = cbits(i = getch())) == ' ' || j == '\t')
181: ;
182: ch = i;
183: copyf--;
184: control(getrq(), 1);
185: flushi();
186: goto loop;
187: }
188: Lt:
189: ch = i;
190: text();
191: if (nlflg)
192: numtab[HP].val = 0;
193: goto loop;
194: }
195:
196:
197: catch()
198: {
199: done3(01);
200: }
201:
202:
203: kcatch()
204: {
205: signal(SIGTERM, SIG_IGN);
206: done3(01);
207: }
208:
209:
210: init0()
211: {
212: eibuf = ibufp = ibuf;
213: ibuf[0] = 0;
214: numtab[NL].val = -1;
215: }
216:
217:
218: init1(a)
219: char a;
220: {
221: register char *p;
222: char *mktemp();
223: register i;
224:
225: p = mktemp("/usr/tmp/trtmpXXXXX");
226: if (a == 'a')
227: p = &p[9];
228: if ((close(creat(p, 0600))) < 0) {
229: errprint("cannot create temp file.");
230: exit(-1);
231: }
232: ibf = open(p, 2);
233: unlkp = p;
234: for (i = NTRTAB; --i; )
235: trtab[i] = i;
236: trtab[UNPAD] = ' ';
237: }
238:
239:
240: init2()
241: {
242: register i;
243: extern char *setbrk();
244:
245: ttyod = 2;
246: iflg = 0;
247: obufp = obuf;
248: ptinit();
249: mchbits();
250: cvtime();
251: numtab[PID].val = getpid();
252: olinep = oline;
253: ioff = 0;
254: numtab[HP].val = init = 0;
255: numtab[NL].val = -1;
256: nfo = 0;
257: ifile = 0;
258: copyf = raw = 0;
259: eibuf = sprintf(ibuf+strlen(ibuf), ".ds .T %s\n", devname);
260: numtab[CD].val = -1; /* compensation */
261: cpushback(ibuf);
262: ibufp = ibuf;
263: nx = mflg;
264: frame = stk = (struct s *)setbrk(DELTA);
265: dip = &d[0];
266: nxf = frame + 1;
267: #ifdef INCORE
268: for (i = 0; i < NEV; i++) {
269: extern tchar corebuf[];
270: envcopy((struct env *) &corebuf[i * sizeof(env)/sizeof(tchar)], &env);
271: }
272: #else
273: for (i = NEV; i--; )
274: write(ibf, (char *) & env, sizeof(env));
275: #endif
276: }
277:
278: #include <time.h>
279:
280: cvtime()
281: {
282: long tt;
283: struct tm *ltime, *localtime();
284:
285: time(&tt);
286: ltime = localtime(&tt);
287: numtab[YR].val = ltime->tm_year;
288: numtab[MO].val = ltime->tm_mon + 1; /* troff uses 1..12 */
289: numtab[DY].val = ltime->tm_mday;
290: numtab[DW].val = ltime->tm_wday + 1; /* troff uses 1..7 */
291:
292: /* register i;
293: /* static int ms[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
294: /* tt -= 3600 * ZONE; /* 5hrs for EST */
295: /* numtab[DY].val = (tt / 86400L) + 1;
296: /* numtab[DW].val = (numtab[DY].val + 3) % 7 + 1;
297: /* for (numtab[YR].val = 70; ; numtab[YR].val++) {
298: /* if ((numtab[YR].val) % 4)
299: /* ms[1] = 28;
300: /* else
301: /* ms[1] = 29;
302: /* for (i = 0; i < 12; ) {
303: /* if (numtab[DY].val <= ms[i]) {
304: /* numtab[MO].val = i + 1;
305: /* return;
306: /* }
307: /* numtab[DY].val -= ms[i++];
308: /* }
309: /* }
310: */
311: }
312:
313:
314: ctoi(s)
315: register char *s;
316: {
317: register n;
318:
319: while (*s == ' ')
320: s++;
321: n = 0;
322: while (isdigit(*s))
323: n = 10 * n + *s++ - '0';
324: return n;
325: }
326:
327:
328: errprint(s, s1, s2, s3, s4, s5) /* error message printer */
329: char *s, *s1, *s2, *s3, *s4, *s5;
330: {
331: fdprintf(stderr, "%s: ", progname);
332: fdprintf(stderr, s, s1, s2, s3, s4, s5);
333: if (numtab[CD].val > 0)
334: fdprintf(stderr, "; line %d, file %s", numtab[CD].val, cfname[ifi]);
335: fdprintf(stderr, "\n");
336: stackdump();
337: }
338:
339:
340: /*
341: * Scaled down version of C Library printf.
342: * Only %s %u %d (==%u) %o %c %x %D are recognized.
343: */
344: #define putchar(n) (*pfbp++ = (n)) /* NO CHECKING! */
345:
346: static char pfbuf[NTM];
347: static char *pfbp = pfbuf;
348: int stderr = 2; /* NOT stdio value */
349:
350: /* VARARGS2 */
351: fdprintf(fd, fmt, x1)
352: int fd;
353: register char *fmt;
354: {
355: register c;
356: register char *adx;
357: char *s;
358: register i;
359:
360: pfbp = pfbuf;
361: adx = (char*)&x1;
362: loop:
363: while ((c = *fmt++) != '%') {
364: if (c == '\0') {
365: if (fd == stderr)
366: write(stderr, pfbuf, (int)(pfbp - pfbuf));
367: else {
368: *pfbp = 0;
369: pfbp = pfbuf;
370: while (*pfbp) {
371: *obufp++ = *pfbp++;
372: if (obufp >= &obuf[OBUFSZ])
373: flusho();
374: }
375: }
376: return;
377: }
378: putchar(c);
379: }
380: c = *fmt++;
381: if (c == 'd') {
382: i = *(int*)adx;
383: if (i < 0) {
384: putchar('-');
385: i = -i;
386: }
387: printn((long)i, 10);
388: adx += sizeof(int);
389: } else if (c == 'u' || c == 'o' || c == 'x') {
390: i = *(int*)adx;
391: printn((long)i, c == 'o' ? 8 : (c == 'x' ? 16 : 10));
392: adx += sizeof(int);
393: }
394: else if (c == 'c') {
395: c = *(int*)adx & 0377;
396: if (c > 0177 || (c < 040 && c != '\n' && c != '\t'))
397: putchar('\\');
398: putchar(c & 0177);
399: adx += sizeof(int);
400: } else if (c == 's') {
401: s = *(char**)adx;
402: while (c = *s++)
403: putchar(c);
404: adx += sizeof(char**);
405: } else if (c == 'D') {
406: printn(*(long*)adx, 10);
407: adx += sizeof(long);
408: } else if (c == 'O') {
409: printn(*(long*)adx, 8);
410: adx += sizeof(long);
411: }
412: goto loop;
413: }
414:
415:
416: /*
417: * Print an unsigned integer in base b.
418: */
419: static printn(n, b)
420: register long n;
421: register b;
422: {
423: char s[20];
424: register char *p;
425: register c;
426:
427: if (n < b) {
428: if(n >= 0) {
429: putchar("0123456789ABCDEF"[n]);
430: return;
431: }
432: putchar('-');
433: n = -n;
434: }
435: p = s+20;
436: *--p = 0;
437: for(;;) {
438: *--p = "0123456789ABCDEF"[n % b];
439: if(!(n /= b))
440: break;
441: }
442: while(c = *p++)
443: putchar(c);
444: }
445:
446: /* scaled down version of library sprintf */
447: /* same limits as fdprintf */
448: /* returns pointer to \0 that ends the string */
449:
450: /* VARARGS2 */
451: char *sprintf(str, fmt, x1)
452: char *str;
453: char *fmt;
454: {
455: register c;
456: register char *adx;
457: char *s;
458: register i;
459:
460: adx = (char*)&x1;
461: loop:
462: while ((c = *fmt++) != '%') {
463: if (c == '\0') {
464: *str = 0;
465: return str;
466: }
467: *str++ = c;
468: }
469: c = *fmt++;
470: if (c == 'd') {
471: i = *(int*)adx;
472: if (i < 0) {
473: *str++ = '-';
474: i = -i;
475: }
476: str = sprintn(str, (long)i, 10);
477: adx += sizeof(int);
478: } else if (c == 'u' || c == 'o' || c == 'x') {
479: i = *(int*)adx;
480: str = sprintn(str, (long)i, c == 'o' ? 8 : (c == 'x' ? 16 : 10));
481: adx += sizeof(int);
482: }
483: else if (c == 'c') {
484: c = *(int*)adx & 0377;
485: if (c > 0177 || c < 040)
486: *str++ = '\\';
487: *str++ = c & 0177;
488: adx += sizeof(int);
489: } else if (c == 's') {
490: s = *(char**)adx;
491: while (c = *s++)
492: *str++ = c;
493: adx += sizeof(char**);
494: } else if (c == 'D') {
495: str = sprintn(str, *(long*)adx, 10);
496: adx += sizeof(long);
497: } else if (c == 'O') {
498: str = sprintn(str, *(long*)adx, 8);
499: adx += sizeof(long);
500: }
501: goto loop;
502: }
503:
504: /*
505: * Print an unsigned integer in base b.
506: */
507: static char *sprintn(s, n, b)
508: register char *s;
509: register long n;
510: {
511: register long a;
512:
513: if (n < 0) { /* shouldn't happen */
514: *s++ = '-';
515: n = -n;
516: }
517: if (a = n / b)
518: s = sprintn(s, a, b);
519: *s++ = "0123456789ABCDEF"[(int)(n%b)];
520: return s;
521: }
522:
523:
524: control(a, b)
525: register int a, b;
526: {
527: register int j;
528:
529: if (a == 0 || (j = findmn(a)) == -1)
530: return(0);
531: if (contab[j].f == 0) {
532: nxf->nargs = 0;
533: if (b)
534: collect();
535: flushi();
536: return pushi(contab[j].mx, a);
537: } else if (b)
538: return((*contab[j].f)(0));
539: else
540: return(0);
541: }
542:
543:
544: getrq()
545: {
546: register i, j;
547:
548: if (((i = getach()) == 0) || ((j = getach()) == 0))
549: goto rtn;
550: i = PAIR(i, j);
551: rtn:
552: return(i);
553: }
554:
555: /*
556: * table encodes some special characters, to speed up tests
557: * in getchar, viz FLSS, RPT, f, \b, \n, fc, tabch, ldrch
558: */
559:
560: char
561: gchtab[] = {
562: 000,004,000,000,010,000,000,000, /* fc, ldr */
563: 001,002,001,000,001,000,000,000, /* \b, tab, nl, RPT */
564: 000,000,000,000,000,000,000,000,
565: 000,001,000,000,000,000,000,000, /* FLSS */
566: 000,000,000,000,000,000,000,000,
567: 000,000,000,000,000,000,000,000,
568: 000,000,000,000,000,000,000,000,
569: 000,000,000,000,000,000,000,000,
570: 000,000,000,000,000,000,000,000,
571: 000,000,000,000,000,000,000,000,
572: 000,000,000,000,000,000,000,000,
573: 000,000,000,000,000,000,000,000,
574: 000,000,000,000,000,000,001,000, /* f */
575: 000,000,000,000,000,000,000,000,
576: 000,000,000,000,000,000,000,000,
577: 000,000,000,000,000,000,000,000,
578: };
579:
580: tchar
581: getch()
582: {
583: register int k;
584: register tchar i, j;
585: tchar setht(), setslant();
586:
587: g0:
588: if(ch) {
589: i = ch;
590: if (cbits(i) == '\n')
591: nlflg++;
592: ch = 0;
593: return(i);
594: }
595:
596: if (nlflg)
597: return('\n');
598: i = getch0();
599: if (ismot(i))
600: return(i);
601: k = cbits(i);
602: if (k != ESC) {
603: if (k >= sizeof(gchtab)/sizeof(gchtab[0]) || gchtab[k] == 0)
604: return(i);
605: if (k == '\n') {
606: if (cbits(i) == '\n') {
607: nlflg++;
608: if (ip == 0)
609: numtab[CD].val++; /* line number */
610: }
611: return(k);
612: }
613: if (k == FLSS) {
614: copyf++;
615: raw++;
616: i = getch0();
617: if (!fi)
618: flss = i;
619: copyf--;
620: raw--;
621: goto g0;
622: }
623: if (k == RPT) {
624: setrpt();
625: goto g0;
626: }
627: if (!copyf) {
628: if (k == 'f' && lg && !lgf) {
629: i = getlg(i);
630: return(i);
631: }
632: if (k == fc || k == tabch || k == ldrch) {
633: if ((i = setfield(k)) == 0)
634: goto g0;
635: else
636: return(i);
637: }
638: if (k == '\b') {
639: i = makem(-width(' ' | chbits));
640: return(i);
641: }
642: }
643: return(i);
644: }
645: k = cbits(j = getch0());
646: if (ismot(j))
647: return(j);
648: switch (k) {
649:
650: case '\n': /* concealed newline */
651: goto g0;
652: case 'n': /* number register */
653: setn();
654: goto g0;
655: case '*': /* string indicator */
656: setstr();
657: goto g0;
658: case '$': /* argument indicator */
659: seta();
660: goto g0;
661: case '{': /* LEFT */
662: i = LEFT;
663: goto gx;
664: case '}': /* RIGHT */
665: i = RIGHT;
666: goto gx;
667: case '"': /* comment */
668: while (cbits(i = getch0()) != '\n')
669: ;
670: nlflg++;
671: if (ip == 0)
672: numtab[CD].val++;
673: return(i);
674: case ESC: /* double backslash */
675: i = eschar;
676: goto gx;
677: case 'e': /* printable version of current eschar */
678: i = PRESC;
679: goto gx;
680: case ' ': /* unpaddable space */
681: i = UNPAD;
682: goto gx;
683: case '\'': /* \(aa */
684: i = ACUTE;
685: goto gx;
686: case '`': /* \(ga */
687: i = GRAVE;
688: goto gx;
689: case '_': /* \(ul */
690: i = UNDERLINE;
691: goto gx;
692: case '-': /* current font minus */
693: i = MINUS;
694: goto gx;
695: case '&': /* filler */
696: i = FILLER;
697: goto gx;
698: case 'c': /* to be continued */
699: i = CONT;
700: goto gx;
701: case '!': /* transparent indicator */
702: i = XPAR;
703: goto gx;
704: case 't': /* tab */
705: i = '\t';
706: return(i);
707: case 'a': /* leader (SOH) */
708: /* old: *pbp++ = LEADER; goto g0; */
709: i = LEADER;
710: return i;
711: case '%': /* ohc */
712: i = OHC;
713: return(i);
714: case 'g': /* return format of a number register */
715: setaf();
716: goto g0;
717: case '.': /* . */
718: i = '.';
719: gx:
720: setsfbits(i, sfbits(j));
721: return(i);
722: }
723: if (copyf) {
724: *pbp++ = j;
725: return(eschar);
726: }
727: switch (k) {
728:
729: case 'p': /* spread */
730: spread++;
731: goto g0;
732: case '(': /* special char name \(xx */
733: case 'C': /* \C'...' */
734: if ((i = setch(k)) == 0)
735: goto g0;
736: return(i);
737: case 'N': /* absolute character number */
738: if ((i = setabs()) == 0)
739: goto g0;
740: return i;
741: case 's': /* size indicator */
742: setps();
743: goto g0;
744: case 'H': /* character height */
745: return(setht());
746: case 'S': /* slant */
747: return(setslant());
748: case 'f': /* font indicator */
749: setfont(0);
750: goto g0;
751: case 'w': /* width function */
752: setwd();
753: goto g0;
754: case 'v': /* vert mot */
755: if (i = vmot())
756: return(i);
757: goto g0;
758: case 'h': /* horiz mot */
759: if (i = hmot())
760: return(i);
761: goto g0;
762: case 'z': /* zero with char */
763: return(setz());
764: case 'l': /* hor line */
765: setline();
766: goto g0;
767: case 'L': /* vert line */
768: setvline();
769: goto g0;
770: case 'D': /* drawing function */
771: setdraw();
772: goto g0;
773: case 'X': /* \X'...' for copy through */
774: setxon();
775: goto g0;
776: case 'b': /* bracket */
777: setbra();
778: goto g0;
779: case 'o': /* overstrike */
780: setov();
781: goto g0;
782: case 'k': /* mark hor place */
783: if ((k = findr(getsn())) != -1) {
784: numtab[k].val = numtab[HP].val;
785: }
786: goto g0;
787: case '0': /* number space */
788: return(makem(width('0' | chbits)));
789: #ifdef NROFF
790: case '|':
791: case '^':
792: goto g0;
793: #else
794: case '|': /* narrow space */
795: return(makem((int)(EM)/6));
796: case '^': /* half narrow space */
797: return(makem((int)(EM)/12));
798: #endif
799: case 'x': /* extra line space */
800: if (i = xlss())
801: return(i);
802: goto g0;
803: case 'u': /* half em up */
804: case 'r': /* full em up */
805: case 'd': /* half em down */
806: return(sethl(k));
807: default:
808: return(j);
809: }
810: /* NOTREACHED */
811: }
812:
813: setxon() /* \X'...' for copy through */
814: {
815: tchar xbuf[NC];
816: register tchar *i;
817: tchar c;
818: int delim, k;
819:
820: if (ismot(c = getch()))
821: return;
822: delim = cbits(c);
823: i = xbuf;
824: *i++ = XON | chbits;
825: while ((k = cbits(c = getch())) != delim && k != '\n' && i < xbuf+NC-1) {
826: if (k == ' ')
827: setcbits(c, UNPAD);
828: *i++ = c | ZBIT;
829: }
830: *i++ = XOFF | chbits;
831: *i = 0;
832: pushback(xbuf);
833: }
834:
835:
836: char ifilt[32] = {
837: 0, 001, 002, 003, 0, 005, 006, 007, 010, 011, 012};
838:
839: tchar
840: getch0()
841: {
842: register int j;
843: register tchar i;
844:
845: again:
846: if (pbp > lastpbp)
847: i = *--pbp;
848: else if (ip) {
849: #ifdef INCORE
850: extern tchar corebuf[];
851: i = corebuf[ip];
852: if (i == 0)
853: i = rbf();
854: else {
855: if ((++ip & (BLK - 1)) == 0) {
856: --ip;
857: (void)rbf();
858: }
859: }
860: #else
861: i = rbf();
862: #endif
863: } else {
864: if (donef || ndone)
865: done(0);
866: if (nx || ibufp >= eibuf) {
867: if (nfo==0) {
868: g0:
869: if (nextfile()) {
870: if (ip)
871: goto again;
872: if (ibufp < eibuf)
873: goto g2;
874: }
875: }
876: nx = 0;
877: if ((j = read(ifile, ibuf, IBUFSZ)) <= 0)
878: goto g0;
879: ibufp = ibuf;
880: eibuf = ibuf + j;
881: if (ip)
882: goto again;
883: }
884: g2:
885: i = *ibufp++ & 0177;
886: ioff++;
887: if (i >= 040 && i < 0177)
888: goto g4;
889: if (i != 0177)
890: i = ifilt[i];
891: }
892: if (cbits(i) == IMP && !raw)
893: goto again;
894: if ((i == 0 || i == 0177) && !init && !raw) {
895: goto again;
896: }
897: g4:
898: if (ismot(i))
899: return i;
900: if (copyf == 0 && sfbits(i) == 0)
901: i |= chbits;
902: if (cbits(i) == eschar && !raw)
903: setcbits(i, ESC);
904: return(i);
905: }
906:
907: pushback(b)
908: register tchar *b;
909: {
910: register tchar *ob = b;
911:
912: while (*b++)
913: ;
914: b--;
915: while (b > ob && pbp < &pbbuf[NC-3])
916: *pbp++ = *--b;
917: if (pbp >= &pbbuf[NC-3]) {
918: errprint("pushback overflow");
919: done(2);
920: }
921: }
922:
923: cpushback(b)
924: register char *b;
925: {
926: register char *ob = b;
927:
928: while (*b++)
929: ;
930: b--;
931: while (b > ob && pbp < &pbbuf[NC-3])
932: *pbp++ = *--b;
933: if (pbp >= &pbbuf[NC-3]) {
934: errprint("cpushback overflow");
935: done(2);
936: }
937: }
938:
939: nextfile()
940: {
941: register char *p;
942:
943: n0:
944: if (ifile)
945: close(ifile);
946: if (nx || nmfi < mflg) {
947: p = mfiles[nmfi++];
948: if (*p != 0)
949: goto n1;
950: }
951: if (ifi > 0) {
952: if (popf())
953: goto n0; /* popf error */
954: return(1); /* popf ok */
955: }
956: if (rargc-- <= 0) {
957: if ((nfo -= mflg) && !stdi)
958: done(0);
959: nfo++;
960: numtab[CD].val = ifile = stdi = mflg = 0;
961: strcpy(cfname[ifi], "<standard input>");
962: ioff = 0;
963: return(0);
964: }
965: p = (argp++)[0];
966: n1:
967: numtab[CD].val = 0;
968: if (p[0] == '-' && p[1] == 0) {
969: ifile = 0;
970: strcpy(cfname[ifi], "<standard input>");
971: } else if ((ifile = open(p, 0)) < 0) {
972: errprint("cannot open file %s", p);
973: nfo -= mflg;
974: done(02);
975: } else
976: strcpy(cfname[ifi],p);
977: nfo++;
978: ioff = 0;
979: return(0);
980: }
981:
982:
983: popf()
984: {
985: register i;
986: register char *p, *q;
987:
988: ioff = offl[--ifi];
989: numtab[CD].val = cfline[ifi]; /*restore line counter*/
990: ip = ipl[ifi];
991: if ((ifile = ifl[ifi]) == 0) {
992: p = xbuf;
993: q = ibuf;
994: ibufp = xbufp;
995: eibuf = xeibuf;
996: while (q < eibuf)
997: *q++ = *p++;
998: return(0);
999: }
1000: if (lseek(ifile, (long)(ioff & ~(IBUFSZ-1)), 0) == (long) -1
1001: || (i = read(ifile, ibuf, IBUFSZ)) < 0)
1002: return(1);
1003: eibuf = ibuf + i;
1004: ibufp = ibuf;
1005: /*
1006: if (ttyname(ifile) == 0)
1007: */
1008: if ((ibufp = ibuf + (int)(ioff & (IBUFSZ - 1))) > eibuf)
1009: return(1);
1010: return(0);
1011: }
1012:
1013:
1014: flushi()
1015: {
1016: if (nflush)
1017: return;
1018: ch = 0;
1019: copyf++;
1020: while (!nlflg) {
1021: if (donef && (frame == stk))
1022: break;
1023: getch();
1024: }
1025: copyf--;
1026: }
1027:
1028:
1029: getach()
1030: {
1031: register tchar i;
1032: register j;
1033:
1034: lgf++;
1035: j = cbits(i = getch());
1036: /* this test ought to be more general and more careful */
1037: if (ismot(i) || j == ' ' || j == '\n' || j == RIGHT || j & 0200) {
1038: ch = i;
1039: j = 0;
1040: }
1041: lgf--;
1042: return(j & 0177);
1043: }
1044:
1045:
1046: casenx()
1047: {
1048: lgf++;
1049: skip();
1050: getname();
1051: nx++;
1052: if (nmfi > 0)
1053: nmfi--;
1054: strcpy(mfiles[nmfi], nextf);
1055: nextfile();
1056: nlflg++;
1057: ip = 0;
1058: pendt = 0;
1059: frame = stk;
1060: nxf = frame + 1;
1061: }
1062:
1063:
1064: getname()
1065: {
1066: register int j, k;
1067: tchar i;
1068:
1069: lgf++;
1070: for (k = 0; k < (NS - 1); k++) {
1071: if (((j = cbits(i = getch())) <= ' ') || (j > 0176))
1072: break;
1073: nextf[k] = j;
1074: }
1075: nextf[k] = 0;
1076: ch = i;
1077: lgf--;
1078: return(nextf[0]);
1079: }
1080:
1081:
1082: caseso()
1083: {
1084: register i;
1085: register char *p, *q;
1086:
1087: lgf++;
1088: nextf[0] = 0;
1089: if (skip() || !getname() || ((i = open(nextf, 0)) < 0) || (ifi >= NSO)) {
1090: errprint("can't open file %s", nextf);
1091: done(02);
1092: }
1093: strcpy(cfname[ifi+1], nextf);
1094: cfline[ifi] = numtab[CD].val; /*hold line counter*/
1095: numtab[CD].val = 0;
1096: flushi();
1097: ifl[ifi] = ifile;
1098: ifile = i;
1099: offl[ifi] = ioff;
1100: ioff = 0;
1101: ipl[ifi] = ip;
1102: ip = 0;
1103: nx++;
1104: nflush++;
1105: if (!ifl[ifi++]) {
1106: p = ibuf;
1107: q = xbuf;
1108: xbufp = ibufp;
1109: xeibuf = eibuf;
1110: while (p < eibuf)
1111: *q++ = *p++;
1112: }
1113: }
1114:
1115: caself() /* set line number and file */
1116: {
1117: int n;
1118:
1119: if (skip())
1120: return;
1121: n = atoi();
1122: cfline[ifi] = numtab[CD].val = n - 2;
1123: if (skip())
1124: return;
1125: if (getname())
1126: strcpy(cfname[ifi], nextf);
1127: }
1128:
1129:
1130: casecf()
1131: { /* copy file without change */
1132: #ifndef NROFF
1133: int fd, n;
1134: char buf[512];
1135: extern int hpos, esc, po;
1136:
1137: lgf++;
1138: nextf[0] = 0;
1139: if (skip() || !getname() || (fd = open(nextf, 0)) < 0) {
1140: errprint("can't open file %s", nextf);
1141: done(02);
1142: }
1143: lgf--;
1144: /* make it into a clean state, be sure that everything is out */
1145: tbreak();
1146: hpos = po;
1147: esc = 0;
1148: ptesc(); /* to left margin */
1149: esc = un;
1150: ptesc();
1151: ptlead();
1152: ptps();
1153: ptfont();
1154: flusho();
1155: while ((n = read(fd, buf, sizeof buf)) > 0)
1156: write(ptid, buf, n);
1157: close(fd);
1158: ptps();
1159: ptfont();
1160: #endif
1161: }
1162:
1163:
1164: casesy() /* call system */
1165: {
1166: char sybuf[NTM];
1167: int i;
1168:
1169: lgf++;
1170: copyf++;
1171: skip();
1172: for (i = 0; i < NTM - 2; i++)
1173: if ((sybuf[i] = getch()) == '\n' || sybuf[i] == RIGHT)
1174: break;
1175: sybuf[i] = 0;
1176: system(sybuf);
1177: copyf--;
1178: lgf--;
1179: }
1180:
1181:
1182: getpn(a)
1183: register char *a;
1184: {
1185: register int n, neg;
1186:
1187: if (*a == 0)
1188: return;
1189: neg = 0;
1190: for ( ; *a; a++)
1191: switch (*a) {
1192: case '+':
1193: case ',':
1194: continue;
1195: case '-':
1196: neg = 1;
1197: continue;
1198: default:
1199: n = 0;
1200: if (isdigit(*a)) {
1201: do
1202: n = 10 * n + *a++ - '0';
1203: while (isdigit(*a));
1204: a--;
1205: } else
1206: n = 9999;
1207: *pnp++ = neg ? -n : n;
1208: neg = 0;
1209: if (pnp >= &pnlist[NPN-2]) {
1210: errprint("too many page numbers");
1211: done3(-3);
1212: }
1213: }
1214: if (neg)
1215: *pnp++ = -9999;
1216: *pnp = -32767;
1217: print = 0;
1218: pnp = pnlist;
1219: if (*pnp != -32767)
1220: chkpn();
1221: }
1222:
1223:
1224: setrpt()
1225: {
1226: tchar i, j;
1227:
1228: copyf++;
1229: raw++;
1230: i = getch0();
1231: copyf--;
1232: raw--;
1233: if (i < 0 || cbits(j = getch0()) == RPT)
1234: return;
1235: i &= BYTEMASK;
1236: while (i>0 && pbp < &pbbuf[NC-3]) {
1237: i--;
1238: *pbp++ = j;
1239: }
1240: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.