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