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