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