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