123879Sjaap #ifndef lint
2*64044Sbostic /*
333922Sjaap static char sccsid[] = "@(#)n1.c 2.2 (CWI) 88/03/31";
4*64044Sbostic */
5*64044Sbostic static char sccsid[] = "@(#)n1.c 2.3 (Berkeley) 07/27/93";
623879Sjaap #endif lint
723901Sjaap /*
823901Sjaap * n1.c
923901Sjaap *
1023901Sjaap * consume options, initialization, main loop,
1123901Sjaap * input routines, escape function calling
1223901Sjaap */
1323901Sjaap
1423879Sjaap #include <ctype.h>
1523901Sjaap #include <signal.h>
1623879Sjaap #include <sys/types.h>
1723879Sjaap #include <sys/stat.h>
1823901Sjaap #include <setjmp.h>
1923901Sjaap #include <sgtty.h>
2023901Sjaap
2123879Sjaap #include "tdef.h"
22*64044Sbostic #include "pathnames.h"
2323901Sjaap #include "ext.h"
2423901Sjaap
2523901Sjaap #include <time.h> /* See cvtime() (jaap) */
2623901Sjaap
2723879Sjaap #ifdef NROFF
2823879Sjaap #include "tw.h"
2923879Sjaap #endif
3023901Sjaap
3123879Sjaap jmp_buf sjbuf;
3223901Sjaap filep ipl[NSO];
3323879Sjaap long offl[NSO];
3423879Sjaap long ioff;
3523879Sjaap char *ttyp;
3623901Sjaap char cfname[NSO][NS] = "<standard input>"; /*file name stack*/
3723901Sjaap int cfline[NSO]; /*input line count stack*/
3823901Sjaap char *progname; /* program name (troff) */
3923879Sjaap
main(argc,argv)4023879Sjaap main(argc, argv)
4123879Sjaap int argc;
4223879Sjaap char **argv;
4323879Sjaap {
4423879Sjaap register char *p, *q;
4523879Sjaap register j;
4623901Sjaap register tchar i;
4723879Sjaap extern catch(), kcatch();
4823901Sjaap char **oargv, *getenv();
4923879Sjaap
5023901Sjaap progname = argv[0];
5123879Sjaap signal(SIGHUP, catch);
5223879Sjaap if (signal(SIGINT, catch) == SIG_IGN) {
5323879Sjaap signal(SIGHUP, SIG_IGN);
5423879Sjaap signal(SIGINT, SIG_IGN);
5523879Sjaap signal(SIGQUIT, SIG_IGN);
5623879Sjaap }
5723879Sjaap signal(SIGPIPE, catch);
5823879Sjaap signal(SIGTERM, kcatch);
5923879Sjaap oargv = argv;
6023901Sjaap mrehash();
6123901Sjaap nrehash();
6223879Sjaap init0();
6323901Sjaap if ((p = getenv("TYPESETTER")) != 0)
6423901Sjaap strcpy(devname, p);
6523879Sjaap while (--argc > 0 && (++argv)[0][0] == '-')
6623879Sjaap switch (argv[0][1]) {
6723879Sjaap
6823879Sjaap case 'F': /* switch font tables from default */
6923879Sjaap if (argv[0][2] != '\0') {
7023879Sjaap strcpy(termtab, &argv[0][2]);
7123879Sjaap strcpy(fontfile, &argv[0][2]);
7223879Sjaap } else {
7323879Sjaap argv++; argc--;
7423879Sjaap strcpy(termtab, argv[0]);
7523879Sjaap strcpy(fontfile, argv[0]);
7623879Sjaap }
7723879Sjaap continue;
7823879Sjaap case 0:
7923879Sjaap goto start;
8023879Sjaap case 'i':
8123879Sjaap stdi++;
8223879Sjaap continue;
8323879Sjaap case 'q':
8423879Sjaap quiet++;
8523879Sjaap if (gtty(0, &ttys) >= 0)
8623879Sjaap ttysave = ttys.sg_flags;
8723879Sjaap continue;
8823879Sjaap case 'n':
8923879Sjaap npn = ctoi(&argv[0][2]);
9023879Sjaap continue;
9123879Sjaap case 'u': /* set emboldening amount */
9223879Sjaap bdtab[3] = ctoi(&argv[0][2]);
9323879Sjaap if (bdtab[3] < 0 || bdtab[3] > 50)
9423879Sjaap bdtab[3] = 0;
9523879Sjaap continue;
9623879Sjaap case 's':
9723879Sjaap if (!(stop = ctoi(&argv[0][2])))
9823879Sjaap stop++;
9923879Sjaap continue;
10023879Sjaap case 'r':
101*64044Sbostic eibuf = ibuf+strlen(ibuf);
102*64044Sbostic (void) sprintf(eibuf, ".nr %c %s\n",
10323879Sjaap argv[0][2], &argv[0][3]);
10423879Sjaap continue;
10523901Sjaap case 'c':
10623879Sjaap case 'm':
10723901Sjaap strcat(nextf, &argv[0][2]);
108*64044Sbostic if (access(nextf, 4) < 0) {
109*64044Sbostic char local[NS];
110*64044Sbostic
111*64044Sbostic strcpy(local, _PATH_LOCAL_TMAC);
112*64044Sbostic strcat(local, &argv[0][2]);
113*64044Sbostic if (access(local, 4) == 0)
114*64044Sbostic strcpy(nextf, local);
115*64044Sbostic }
11623879Sjaap mflg++;
11723879Sjaap continue;
11823879Sjaap case 'o':
11923879Sjaap getpn(&argv[0][2]);
12023879Sjaap continue;
12123901Sjaap case 'T':
12223901Sjaap strcpy(devname, &argv[0][2]);
12323901Sjaap dotT++;
12423901Sjaap continue;
12523901Sjaap case 'D': /* select DUTCH as hyphenation style (jaap) */
12623879Sjaap hyalg1 = hyalg = DUTCH;
12723879Sjaap thresh = DUTCH_THRESH;
12823879Sjaap continue;
12923879Sjaap #ifdef NROFF
13023879Sjaap case 'h':
13123879Sjaap hflg++;
13223879Sjaap continue;
13323879Sjaap case 'z':
13423879Sjaap no_out++;
13523879Sjaap continue;
13623879Sjaap case 'e':
13723879Sjaap eqflg++;
13823879Sjaap continue;
13923879Sjaap #endif
14023879Sjaap #ifndef NROFF
14123879Sjaap case 'z':
14223879Sjaap no_out++;
14323879Sjaap case 'a':
14423879Sjaap ascii = 1;
14523879Sjaap nofeed++;
14623879Sjaap continue;
14723879Sjaap case 'f':
14823879Sjaap nofeed++;
14923879Sjaap continue;
15023901Sjaap case 't': /* for backward compatability */
15123901Sjaap continue;
15223879Sjaap #endif
15323879Sjaap default:
15423901Sjaap errprint("unknown option %s", argv[0]);
15523879Sjaap done(02);
15623879Sjaap }
15723879Sjaap
15823879Sjaap start:
15923879Sjaap init1(oargv[0][0]);
16023879Sjaap argp = argv;
16123879Sjaap rargc = argc;
16223879Sjaap init2();
16323879Sjaap setjmp(sjbuf);
16423879Sjaap loop:
16523879Sjaap copyf = lgf = nb = nflush = nlflg = 0;
16623879Sjaap if (ip && rbf0(ip) == 0 && ejf && frame->pframe <= ejl) {
16723879Sjaap nflush++;
16823879Sjaap trap = 0;
16923879Sjaap eject((struct s *)0);
17023879Sjaap goto loop;
17123879Sjaap }
17223879Sjaap i = getch();
17323879Sjaap if (pendt)
17423901Sjaap goto Lt;
17523879Sjaap if ((j = cbits(i)) == XPAR) {
17623879Sjaap copyf++;
17723879Sjaap tflg++;
17823879Sjaap while (cbits(i) != '\n')
17923879Sjaap pchar(i = getch());
18023879Sjaap tflg = 0;
18123879Sjaap copyf--;
18223879Sjaap goto loop;
18323879Sjaap }
18423879Sjaap if (j == cc || j == c2) {
18523879Sjaap if (j == c2)
18623879Sjaap nb++;
18723879Sjaap copyf++;
18823879Sjaap while ((j = cbits(i = getch())) == ' ' || j == '\t')
18923879Sjaap ;
19023879Sjaap ch = i;
19123879Sjaap copyf--;
19223879Sjaap control(getrq(), 1);
19323879Sjaap flushi();
19423879Sjaap goto loop;
19523879Sjaap }
19623901Sjaap Lt:
19723879Sjaap ch = i;
19823879Sjaap text();
19923901Sjaap if (nlflg)
20023901Sjaap numtab[HP].val = 0;
20123879Sjaap goto loop;
20223879Sjaap }
20323879Sjaap
20423879Sjaap
catch()20523879Sjaap catch()
20623879Sjaap {
20723879Sjaap done3(01);
20823879Sjaap }
20923879Sjaap
21023879Sjaap
kcatch()21123879Sjaap kcatch()
21223879Sjaap {
21323879Sjaap signal(SIGTERM, SIG_IGN);
21423879Sjaap done3(01);
21523879Sjaap }
21623879Sjaap
21723879Sjaap
init0()21823879Sjaap init0()
21923879Sjaap {
22023879Sjaap eibuf = ibufp = ibuf;
22123879Sjaap ibuf[0] = 0;
22223901Sjaap numtab[NL].val = -1;
22323879Sjaap }
22423879Sjaap
22523879Sjaap
init1(a)22623879Sjaap init1(a)
22723879Sjaap char a;
22823879Sjaap {
22923879Sjaap register i;
23023879Sjaap
23123879Sjaap for (i = NTRTAB; --i; )
23223879Sjaap trtab[i] = i;
23323879Sjaap trtab[UNPAD] = ' ';
23423879Sjaap }
23523879Sjaap
23623879Sjaap
init2()23723879Sjaap init2()
23823879Sjaap {
23923879Sjaap register i, j;
24023879Sjaap extern char *ttyname();
241*64044Sbostic char *cp;
24223879Sjaap
24323879Sjaap ttyod = 2;
24423879Sjaap if ((ttyp=ttyname(j=0)) != 0 || (ttyp=ttyname(j=1)) != 0 || (ttyp=ttyname(j=2)) != 0)
24523879Sjaap ;
24623879Sjaap else
24723879Sjaap ttyp = "notty";
24823879Sjaap iflg = j;
24923879Sjaap if (ascii)
25023879Sjaap mesg(0);
25123879Sjaap ptinit();
25223879Sjaap mchbits();
25323879Sjaap cvtime();
25423901Sjaap numtab[PID].val = getpid();
25523879Sjaap olinep = oline;
25623879Sjaap ioff = 0;
25723901Sjaap numtab[HP].val = init = 0;
25823901Sjaap numtab[NL].val = -1;
25923879Sjaap nfo = 0;
26023879Sjaap ifile = 0;
26123879Sjaap copyf = raw = 0;
262*64044Sbostic cp = ibuf + strlen(ibuf);
263*64044Sbostic sprintf(cp, ".ds .T %s\n", devname);
264*64044Sbostic eibuf = cp + strlen(cp);
26523901Sjaap numtab[CD].val = -1; /* compensation */
26623901Sjaap cpushback(ibuf);
26723879Sjaap ibufp = ibuf;
26823879Sjaap nx = mflg;
269*64044Sbostic frame = stk = (struct s *)malloc(DELTA * sizeof(struct s));
27023879Sjaap dip = &d[0];
27123879Sjaap nxf = frame + 1;
272*64044Sbostic for (i = 1; i < NEV; ++i)
273*64044Sbostic env_array[i] = *env;
27423879Sjaap }
27523879Sjaap
27623901Sjaap /*
27723901Sjaap * (jaap)
27823901Sjaap * This replaces the old cvtime, so on well maintained systems, you don't
27923901Sjaap * need to change the (quite unknown) ZONE constant in tdef.h
28023901Sjaap */
28123901Sjaap
cvtime()28223879Sjaap cvtime() {
28323879Sjaap long tt;
28423879Sjaap register struct tm *tym;
28523879Sjaap extern struct tm *localtime();
28623879Sjaap
28723879Sjaap time(&tt);
28823879Sjaap tym = localtime(&tt);
28923901Sjaap numtab[DY].val = tym->tm_mday; /* Current day of the month */
29023901Sjaap numtab[DW].val = tym->tm_wday + 1; /* Current day of the week */
29123901Sjaap numtab[YR].val = tym->tm_year; /* Current year */
29223901Sjaap numtab[MO].val = tym->tm_mon + 1; /* Current month of year */
29323879Sjaap }
29423879Sjaap
29523901Sjaap
ctoi(s)29623879Sjaap ctoi(s)
29723879Sjaap register char *s;
29823879Sjaap {
29923879Sjaap register n;
30023879Sjaap
30123879Sjaap while (*s == ' ')
30223879Sjaap s++;
30323879Sjaap n = 0;
30423879Sjaap while (isdigit(*s))
30523879Sjaap n = 10 * n + *s++ - '0';
30623879Sjaap return n;
30723879Sjaap }
30823879Sjaap
30923879Sjaap
mesg(f)31023879Sjaap mesg(f)
31123879Sjaap int f;
31223879Sjaap {
31323879Sjaap static int mode;
31423901Sjaap struct stat stbuf;
31523879Sjaap
31623879Sjaap if (!f) {
31723901Sjaap stat(ttyp, &stbuf);
31823901Sjaap mode = stbuf.st_mode;
31923879Sjaap chmod(ttyp, mode & ~0122); /* turn off writing for others */
32023879Sjaap } else {
32123901Sjaap if (ttyp && *ttyp && mode)
32223879Sjaap chmod(ttyp, mode);
32323879Sjaap }
32423879Sjaap }
32523879Sjaap
errprint(s,s1,s2,s3,s4,s5)32623901Sjaap errprint(s, s1, s2, s3, s4, s5) /* error message printer */
32723901Sjaap char *s, *s1, *s2, *s3, *s4, *s5;
32823901Sjaap {
32923901Sjaap fdprintf(stderr, "%s: ", progname);
33023901Sjaap fdprintf(stderr, s, s1, s2, s3, s4, s5);
33123901Sjaap if (numtab[CD].val > 0)
33223901Sjaap fdprintf(stderr, "; line %d, file %s", numtab[CD].val, cfname[ifi]);
33323901Sjaap fdprintf(stderr, "\n");
33423901Sjaap stackdump();
33523901Sjaap }
33623879Sjaap
control(a,b)33723879Sjaap control(a, b)
33823879Sjaap register int a, b;
33923879Sjaap {
34023879Sjaap register int j;
34123879Sjaap
34223879Sjaap if (a == 0 || (j = findmn(a)) == -1)
34323879Sjaap return(0);
34423901Sjaap if (contab[j].f == 0) {
34523879Sjaap nxf->nargs = 0;
34623879Sjaap if (b)
34723879Sjaap collect();
34823879Sjaap flushi();
34923901Sjaap return pushi((filep)contab[j].mx, a);
35023879Sjaap } else if (b)
35123901Sjaap return((*contab[j].f)(0));
35223879Sjaap else
35323879Sjaap return(0);
35423879Sjaap }
35523879Sjaap
35623879Sjaap
getrq()35723879Sjaap getrq()
35823879Sjaap {
35923879Sjaap register i, j;
36023879Sjaap
36123879Sjaap if (((i = getach()) == 0) || ((j = getach()) == 0))
36223879Sjaap goto rtn;
36323879Sjaap i = PAIR(i, j);
36423879Sjaap rtn:
36523879Sjaap return(i);
36623879Sjaap }
36723879Sjaap
36823901Sjaap /*
36923901Sjaap * table encodes some special characters, to speed up tests
37023901Sjaap * in getchar, viz FLSS, RPT, f, \b, \n, fc, tabch, ldrch
37123901Sjaap */
37223879Sjaap
37323901Sjaap char
37423901Sjaap gchtab[] = {
37523901Sjaap 000,004,000,000,010,000,000,000, /* fc, ldr */
37623901Sjaap 001,002,001,000,001,000,000,000, /* \b, tab, nl, RPT */
37723901Sjaap 000,000,000,000,000,000,000,000,
37823901Sjaap 000,001,000,000,000,000,000,000, /* FLSS */
37923901Sjaap 000,000,000,000,000,000,000,000,
38023901Sjaap 000,000,000,000,000,000,000,000,
38123901Sjaap 000,000,000,000,000,000,000,000,
38223901Sjaap 000,000,000,000,000,000,000,000,
38323901Sjaap 000,000,000,000,000,000,000,000,
38423901Sjaap 000,000,000,000,000,000,000,000,
38523901Sjaap 000,000,000,000,000,000,000,000,
38623901Sjaap 000,000,000,000,000,000,000,000,
38723901Sjaap 000,000,000,000,000,000,001,000, /* f */
38823901Sjaap 000,000,000,000,000,000,000,000,
38923901Sjaap 000,000,000,000,000,000,000,000,
39023901Sjaap 000,000,000,000,000,000,000,000,
39123901Sjaap };
39223901Sjaap
39323901Sjaap tchar
getch()39423901Sjaap getch()
39523879Sjaap {
39623879Sjaap register int k;
39723901Sjaap register tchar i, j;
39823879Sjaap tchar setht(), setslant();
39923879Sjaap
40023879Sjaap g0:
40123901Sjaap if (i = ch) {
40223901Sjaap if (cbits(i) == '\n')
40323879Sjaap nlflg++;
40423879Sjaap ch = 0;
40523879Sjaap return(i);
40623879Sjaap }
40723879Sjaap
40823901Sjaap if (nlflg)
40923879Sjaap return('\n');
41023901Sjaap i = getch0();
41123901Sjaap if (ismot(i))
41223901Sjaap return(i);
41323901Sjaap k = cbits(i);
41423901Sjaap if (k != ESC) {
41523901Sjaap if (gchtab[k]==0)
41623901Sjaap return(i);
41723901Sjaap if (k == '\n') {
41823901Sjaap if (cbits(i) == '\n') {
41923901Sjaap nlflg++;
42023901Sjaap if (ip == 0)
42123901Sjaap numtab[CD].val++; /* line number */
42223901Sjaap }
42323901Sjaap return(k);
42423901Sjaap }
42523879Sjaap if (k == FLSS) {
42623879Sjaap copyf++;
42723879Sjaap raw++;
42823879Sjaap i = getch0();
42923879Sjaap if (!fi)
43023879Sjaap flss = i;
43123879Sjaap copyf--;
43223879Sjaap raw--;
43323879Sjaap goto g0;
43423879Sjaap }
43523879Sjaap if (k == RPT) {
43623879Sjaap setrpt();
43723879Sjaap goto g0;
43823879Sjaap }
43923879Sjaap if (!copyf) {
44023879Sjaap if (k == 'f' && lg && !lgf) {
44123879Sjaap i = getlg(i);
44223901Sjaap return(i);
44323879Sjaap }
44423879Sjaap if (k == fc || k == tabch || k == ldrch) {
44523879Sjaap if ((i = setfield(k)) == 0)
44623879Sjaap goto g0;
44723879Sjaap else
44823901Sjaap return(i);
44923879Sjaap }
45023879Sjaap if (k == '\b') {
45123879Sjaap i = makem(-width(' ' | chbits));
45223901Sjaap return(i);
45323879Sjaap }
45423879Sjaap }
45523901Sjaap return(i);
45623879Sjaap }
45723879Sjaap k = cbits(j = getch0());
45823901Sjaap if (ismot(j))
45923901Sjaap return(j);
46023879Sjaap switch (k) {
46123879Sjaap
46223879Sjaap case '\n': /* concealed newline */
46323879Sjaap goto g0;
46423879Sjaap case 'n': /* number register */
46523879Sjaap setn();
46623879Sjaap goto g0;
46723879Sjaap case '*': /* string indicator */
46823879Sjaap setstr();
46923879Sjaap goto g0;
47023879Sjaap case '$': /* argument indicator */
47123879Sjaap seta();
47223879Sjaap goto g0;
47323879Sjaap case '{': /* LEFT */
47423879Sjaap i = LEFT;
47523879Sjaap goto gx;
47623879Sjaap case '}': /* RIGHT */
47723879Sjaap i = RIGHT;
47823879Sjaap goto gx;
47923879Sjaap case '"': /* comment */
48023879Sjaap while (cbits(i = getch0()) != '\n')
48123879Sjaap ;
48223901Sjaap nlflg++;
48323901Sjaap if (ip == 0)
48423901Sjaap numtab[CD].val++;
48523901Sjaap return(i);
48623879Sjaap case ESC: /* double backslash */
48723879Sjaap i = eschar;
48823879Sjaap goto gx;
48923879Sjaap case 'e': /* printable version of current eschar */
49023879Sjaap i = PRESC;
49123879Sjaap goto gx;
49223879Sjaap case ' ': /* unpaddable space */
49323879Sjaap i = UNPAD;
49423879Sjaap goto gx;
49523879Sjaap case '\'': /* \(aa */
49623879Sjaap i = ACUTE;
49723879Sjaap goto gx;
49823879Sjaap case '`': /* \(ga */
49923879Sjaap i = GRAVE;
50023879Sjaap goto gx;
50123879Sjaap case '_': /* \(ul */
50223879Sjaap i = UNDERLINE;
50323879Sjaap goto gx;
50423879Sjaap case '-': /* current font minus */
50523879Sjaap i = MINUS;
50623879Sjaap goto gx;
50723879Sjaap case '&': /* filler */
50823879Sjaap i = FILLER;
50923879Sjaap goto gx;
51023879Sjaap case 'c': /* to be continued */
51123879Sjaap i = CONT;
51223879Sjaap goto gx;
51323879Sjaap case '!': /* transparent indicator */
51423879Sjaap i = XPAR;
51523879Sjaap goto gx;
51623879Sjaap case 't': /* tab */
51723879Sjaap i = '\t';
51823901Sjaap return(i);
51923879Sjaap case 'a': /* leader (SOH) */
52023879Sjaap i = LEADER;
52123901Sjaap return(i);
52223879Sjaap case '%': /* ohc */
52323879Sjaap i = OHC;
52423901Sjaap return(i);
52523879Sjaap case 'g': /* return format of a number register */
52623879Sjaap setaf();
52723879Sjaap goto g0;
52823901Sjaap case 'N': /* absolute character number */
52923901Sjaap i = setabs();
53023901Sjaap goto gx;
53123879Sjaap case '.': /* . */
53223879Sjaap i = '.';
53323879Sjaap gx:
53423879Sjaap setsfbits(i, sfbits(j));
53523901Sjaap return(i);
53623879Sjaap }
53723901Sjaap if (copyf) {
53823901Sjaap *pbp++ = j;
53923901Sjaap return(eschar);
54023901Sjaap }
54123901Sjaap switch (k) {
54223879Sjaap
54333922Sjaap case 'X': /* \X'...' for copy through */
54433922Sjaap setxon();
54533922Sjaap goto g0;
54623901Sjaap case 'p': /* spread */
54723901Sjaap spread++;
54823901Sjaap goto g0;
54923901Sjaap case '(': /* special char name */
55023901Sjaap if ((i = setch()) == 0)
55123879Sjaap goto g0;
55223901Sjaap return(i);
55323901Sjaap case 's': /* size indicator */
55423901Sjaap setps();
55523901Sjaap goto g0;
55623901Sjaap case 'H': /* character height */
55723901Sjaap return(setht());
55823901Sjaap case 'S': /* slant */
55923901Sjaap return(setslant());
56023901Sjaap case 'f': /* font indicator */
56123901Sjaap setfont(0);
56223901Sjaap goto g0;
56323901Sjaap case 'w': /* width function */
56423901Sjaap setwd();
56523901Sjaap goto g0;
56623901Sjaap case 'v': /* vert mot */
56723901Sjaap if (i = vmot())
56823901Sjaap return(i);
56923901Sjaap goto g0;
57023901Sjaap case 'h': /* horiz mot */
57123901Sjaap if (i = hmot())
57223901Sjaap return(i);
57323901Sjaap goto g0;
57423901Sjaap case 'z': /* zero with char */
57523901Sjaap return(setz());
57623901Sjaap case 'l': /* hor line */
57723901Sjaap setline();
57823901Sjaap goto g0;
57923901Sjaap case 'L': /* vert line */
58023901Sjaap setvline();
58123901Sjaap goto g0;
58223901Sjaap case 'D': /* drawing function */
58323901Sjaap setdraw();
58423901Sjaap goto g0;
58523901Sjaap case 'b': /* bracket */
58623901Sjaap setbra();
58723901Sjaap goto g0;
58823901Sjaap case 'o': /* overstrike */
58923901Sjaap setov();
59023901Sjaap goto g0;
59123901Sjaap case 'k': /* mark hor place */
59223901Sjaap if ((k = findr(getsn())) != -1) {
59323901Sjaap numtab[k].val = numtab[HP].val;
59423879Sjaap }
59523901Sjaap goto g0;
59623901Sjaap case '0': /* number space */
59723901Sjaap return(makem(width('0' | chbits)));
59823901Sjaap #ifdef NROFF
59923901Sjaap case '|':
60023901Sjaap case '^':
60123901Sjaap goto g0;
60223901Sjaap #else
60323901Sjaap case '|': /* narrow space */
60423901Sjaap return(makem((int)(EM)/6));
60523901Sjaap case '^': /* half narrow space */
60623901Sjaap return(makem((int)(EM)/12));
60723901Sjaap #endif
60823901Sjaap case 'x': /* extra line space */
60923901Sjaap if (i = xlss())
61023901Sjaap return(i);
61123901Sjaap goto g0;
61223901Sjaap case 'u': /* half em up */
61323901Sjaap case 'r': /* full em up */
61423901Sjaap case 'd': /* half em down */
61523901Sjaap return(sethl(k));
61623901Sjaap default:
61723901Sjaap return(j);
61823879Sjaap }
61923901Sjaap /* NOTREACHED */
62023901Sjaap }
62123901Sjaap
setxon()62223901Sjaap setxon() /* \X'...' for copy through */
62323901Sjaap {
62423901Sjaap tchar xbuf[NC];
62523901Sjaap register tchar *i;
62623901Sjaap tchar c;
62723901Sjaap int delim, k;
62823901Sjaap
62923901Sjaap if (ismot(c = getch()))
63023901Sjaap return;
63123901Sjaap delim = cbits(c);
63223901Sjaap i = xbuf;
63323901Sjaap *i++ = XON;
63423901Sjaap while ((k = cbits(c = getch())) != delim && k != '\n' && i < xbuf+NC-1) {
63523901Sjaap if (k == ' ')
63623901Sjaap setcbits(c, UNPAD);
63723901Sjaap *i++ = c | ZBIT;
63823879Sjaap }
63923901Sjaap *i++ = XOFF;
64023901Sjaap *i = 0;
64123901Sjaap pushback(xbuf);
64223879Sjaap }
64323879Sjaap
64423879Sjaap
645*64044Sbostic #ifdef notdef
64623879Sjaap char ifilt[32] = {
64723879Sjaap 0, 001, 002, 003, 0, 005, 006, 007, 010, 011, 012};
648*64044Sbostic #endif
64923879Sjaap
getch0()65023879Sjaap tchar getch0()
65123879Sjaap {
65223879Sjaap register int j;
65323901Sjaap register tchar i;
65423879Sjaap
65523879Sjaap again:
65623901Sjaap if (pbp > lastpbp)
65723901Sjaap i = *--pbp;
65823901Sjaap else if (ip) {
65923901Sjaap #ifdef INCORE
66023901Sjaap extern tchar corebuf[];
66123901Sjaap i = corebuf[ip];
66223901Sjaap if (i == 0)
66323901Sjaap i = rbf();
66423901Sjaap else {
66523901Sjaap if ((++ip & (BLK - 1)) == 0) {
66623901Sjaap --ip;
66723901Sjaap (void)rbf();
66823901Sjaap }
66923879Sjaap }
67023901Sjaap #else
67123901Sjaap i = rbf();
67223901Sjaap #endif
67323879Sjaap } else {
67423879Sjaap if (donef)
67523879Sjaap done(0);
67623879Sjaap if (nx || ibufp >= eibuf) {
67723901Sjaap if (nfo==0) {
67823879Sjaap g0:
67923901Sjaap if (nextfile()) {
68023901Sjaap if (ip)
68123901Sjaap goto again;
68223901Sjaap if (ibufp < eibuf)
68323901Sjaap goto g2;
68423901Sjaap }
68523879Sjaap }
68623879Sjaap nx = 0;
68723879Sjaap if ((j = read(ifile, ibuf, IBUFSZ)) <= 0)
68823879Sjaap goto g0;
68923879Sjaap ibufp = ibuf;
69023879Sjaap eibuf = ibuf + j;
69123879Sjaap if (ip)
69223879Sjaap goto again;
69323879Sjaap }
69423879Sjaap g2:
69523879Sjaap i = *ibufp++ & 0177;
69623879Sjaap ioff++;
69723901Sjaap if (i >= 040 && i < 0177)
69823901Sjaap goto g4;
699*64044Sbostic #ifdef notdef
70023901Sjaap if (i != 0177)
70123879Sjaap i = ifilt[i];
702*64044Sbostic #endif
70323879Sjaap }
70423901Sjaap if (cbits(i) == IMP && !raw)
70523879Sjaap goto again;
70623901Sjaap if ((i == 0 || i == 0177) && !init && !raw) {
70723879Sjaap goto again;
70823901Sjaap }
70923879Sjaap g4:
71023901Sjaap if (copyf == 0 && (i & ~BYTEMASK) == 0)
71123879Sjaap i |= chbits;
71223901Sjaap if (cbits(i) == eschar && !raw)
71323879Sjaap setcbits(i, ESC);
71423879Sjaap return(i);
71523879Sjaap }
71623879Sjaap
pushback(b)71723901Sjaap pushback(b)
71823901Sjaap register tchar *b;
71923901Sjaap {
72023901Sjaap register tchar *ob = b;
72123879Sjaap
72223901Sjaap while (*b++)
72323901Sjaap ;
72423901Sjaap b--;
72523901Sjaap while (b > ob && pbp < &pbbuf[NC-3])
72623901Sjaap *pbp++ = *--b;
72723901Sjaap if (pbp >= &pbbuf[NC-3]) {
72823901Sjaap errprint("pushback overflow");
72923901Sjaap done(2);
73023901Sjaap }
73123901Sjaap }
73223901Sjaap
cpushback(b)73323901Sjaap cpushback(b)
73423901Sjaap register char *b;
73523901Sjaap {
73623901Sjaap register char *ob = b;
73723901Sjaap
73823901Sjaap while (*b++)
73923901Sjaap ;
74023901Sjaap b--;
74123901Sjaap while (b > ob && pbp < &pbbuf[NC-3])
74223901Sjaap *pbp++ = *--b;
74323901Sjaap if (pbp >= &pbbuf[NC-3]) {
74423901Sjaap errprint("cpushback overflow");
74523901Sjaap done(2);
74623901Sjaap }
74723901Sjaap }
74823901Sjaap
nextfile()74923879Sjaap nextfile()
75023879Sjaap {
75123879Sjaap register char *p;
75223879Sjaap
75323879Sjaap n0:
75423879Sjaap if (ifile)
75523879Sjaap close(ifile);
75623879Sjaap if (nx) {
75723879Sjaap p = nextf;
75823879Sjaap if (*p != 0)
75923879Sjaap goto n1;
76023879Sjaap }
76123879Sjaap if (ifi > 0) {
76223879Sjaap if (popf())
76323879Sjaap goto n0; /* popf error */
76423879Sjaap return(1); /* popf ok */
76523879Sjaap }
76623879Sjaap if (rargc-- <= 0) {
76723901Sjaap if ((nfo -= mflg) && !stdi)
76823901Sjaap done(0);
76923901Sjaap nfo++;
77023901Sjaap numtab[CD].val = ifile = stdi = mflg = 0;
77123901Sjaap strcpy(cfname[ifi], "<standard input>");
77223901Sjaap ioff = 0;
77323901Sjaap return(0);
77423879Sjaap }
77523879Sjaap p = (argp++)[0];
77623879Sjaap n1:
77723901Sjaap numtab[CD].val = 0;
77823901Sjaap if (p[0] == '-' && p[1] == 0) {
77923879Sjaap ifile = 0;
78023901Sjaap strcpy(cfname[ifi], "<standard input>");
78123879Sjaap } else if ((ifile = open(p, 0)) < 0) {
78223901Sjaap errprint("cannot open file %s", p);
78323879Sjaap nfo -= mflg;
78423879Sjaap done(02);
78523901Sjaap } else
78623901Sjaap strcpy(cfname[ifi],p);
78723879Sjaap nfo++;
78823879Sjaap ioff = 0;
78923879Sjaap return(0);
79023879Sjaap }
79123879Sjaap
79223879Sjaap
popf()79323879Sjaap popf()
79423879Sjaap {
79523879Sjaap register i;
79623879Sjaap register char *p, *q;
79723879Sjaap extern char *ttyname();
79823879Sjaap
79923879Sjaap ioff = offl[--ifi];
80023901Sjaap numtab[CD].val = cfline[ifi]; /*restore line counter*/
80123879Sjaap ip = ipl[ifi];
80223879Sjaap if ((ifile = ifl[ifi]) == 0) {
80323879Sjaap p = xbuf;
80423879Sjaap q = ibuf;
80523879Sjaap ibufp = xbufp;
80623879Sjaap eibuf = xeibuf;
80723879Sjaap while (q < eibuf)
80823879Sjaap *q++ = *p++;
80923879Sjaap return(0);
81023879Sjaap }
81123901Sjaap if (lseek(ifile, (long)(ioff & ~(IBUFSZ-1)), 0) == (long) -1
81223901Sjaap || (i = read(ifile, ibuf, IBUFSZ)) < 0)
81323879Sjaap return(1);
81423879Sjaap eibuf = ibuf + i;
81523879Sjaap ibufp = ibuf;
81623879Sjaap if (ttyname(ifile) == 0)
81723901Sjaap /* was >= ... */
81823901Sjaap if ((ibufp = ibuf + (int)(ioff & (IBUFSZ - 1))) > eibuf)
81923879Sjaap return(1);
82023879Sjaap return(0);
82123879Sjaap }
82223879Sjaap
82323879Sjaap
flushi()82423879Sjaap flushi()
82523879Sjaap {
82623879Sjaap if (nflush)
82723879Sjaap return;
82823879Sjaap ch = 0;
82923879Sjaap copyf++;
83023879Sjaap while (!nlflg) {
83123879Sjaap if (donef && (frame == stk))
83223879Sjaap break;
83323879Sjaap getch();
83423879Sjaap }
83523879Sjaap copyf--;
83623879Sjaap }
83723879Sjaap
83823879Sjaap
getach()83923879Sjaap getach()
84023879Sjaap {
84123901Sjaap register tchar i;
84223879Sjaap register j;
84323879Sjaap
84423879Sjaap lgf++;
84523879Sjaap j = cbits(i = getch());
84623879Sjaap if (ismot(i) || j == ' ' || j == '\n' || j & 0200) {
84723879Sjaap ch = i;
84823879Sjaap j = 0;
84923879Sjaap }
85023879Sjaap lgf--;
85123879Sjaap return(j & 0177);
85223879Sjaap }
85323879Sjaap
85423879Sjaap
casenx()85523879Sjaap casenx()
85623879Sjaap {
85723879Sjaap lgf++;
85823879Sjaap skip();
85923879Sjaap getname();
86023879Sjaap nx++;
86123879Sjaap nextfile();
86223879Sjaap nlflg++;
86323879Sjaap ip = 0;
86423901Sjaap pendt = 0;
86523879Sjaap frame = stk;
86623879Sjaap nxf = frame + 1;
86723879Sjaap }
86823879Sjaap
86923879Sjaap
getname()87023879Sjaap getname()
87123879Sjaap {
87223879Sjaap register int j, k;
87323879Sjaap tchar i;
87423879Sjaap
87523879Sjaap lgf++;
87623879Sjaap for (k = 0; k < (NS - 1); k++) {
87723879Sjaap if (((j = cbits(i = getch())) <= ' ') || (j > 0176))
87823879Sjaap break;
87923879Sjaap nextf[k] = j;
88023879Sjaap }
88123879Sjaap nextf[k] = 0;
88223879Sjaap ch = i;
88323879Sjaap lgf--;
88423879Sjaap return(nextf[0]);
88523879Sjaap }
88623879Sjaap
88723879Sjaap
caseso()88823879Sjaap caseso()
88923879Sjaap {
89023879Sjaap register i;
89123879Sjaap register char *p, *q;
89223879Sjaap
89323879Sjaap lgf++;
89423879Sjaap nextf[0] = 0;
89523879Sjaap if (skip() || !getname() || ((i = open(nextf, 0)) < 0) || (ifi >= NSO)) {
89623901Sjaap errprint("can't open file %s", nextf);
89723879Sjaap done(02);
89823879Sjaap }
89923901Sjaap strcpy(cfname[ifi+1], nextf);
90023901Sjaap cfline[ifi] = numtab[CD].val; /*hold line counter*/
90123901Sjaap numtab[CD].val = 0;
90223879Sjaap flushi();
90323879Sjaap ifl[ifi] = ifile;
90423879Sjaap ifile = i;
90523879Sjaap offl[ifi] = ioff;
90623879Sjaap ioff = 0;
90723879Sjaap ipl[ifi] = ip;
90823879Sjaap ip = 0;
90923879Sjaap nx++;
91023879Sjaap nflush++;
91123879Sjaap if (!ifl[ifi++]) {
91223879Sjaap p = ibuf;
91323879Sjaap q = xbuf;
91423879Sjaap xbufp = ibufp;
91523879Sjaap xeibuf = eibuf;
91623879Sjaap while (p < eibuf)
91723879Sjaap *q++ = *p++;
91823879Sjaap }
91923879Sjaap }
92023879Sjaap
caself()92123901Sjaap caself() /* set line number and file */
92223901Sjaap {
92323901Sjaap int n;
92423879Sjaap
92523901Sjaap if (skip())
92623901Sjaap return;
92723901Sjaap n = atoi();
92823901Sjaap cfline[ifi] = numtab[CD].val = n - 2;
92923901Sjaap if (skip())
93023901Sjaap return;
93123901Sjaap if (getname())
93223901Sjaap strcpy(cfname[ifi], nextf);
93323901Sjaap }
93423901Sjaap
93523901Sjaap
casecf()93623879Sjaap casecf()
93723879Sjaap { /* copy file without change */
93823879Sjaap #ifndef NROFF
93923879Sjaap int fd, n;
940*64044Sbostic char buf[8192];
94123901Sjaap extern int hpos, esc, po;
94223879Sjaap nextf[0] = 0;
94323879Sjaap if (skip() || !getname() || (fd = open(nextf, 0)) < 0) {
94423901Sjaap errprint("can't open file %s", nextf);
94523879Sjaap done(02);
94623879Sjaap }
94723879Sjaap tbreak();
94823879Sjaap /* make it into a clean state, be sure that everything is out */
94923879Sjaap hpos = po;
95023879Sjaap esc = un;
95123879Sjaap ptesc();
95223879Sjaap ptlead();
95323879Sjaap ptps();
95423879Sjaap ptfont();
95523879Sjaap flusho();
95623901Sjaap while ((n = read(fd, buf, sizeof buf)) > 0)
957*64044Sbostic write(fileno(ptid), buf, n);
95823879Sjaap close(fd);
95923879Sjaap #endif
96023879Sjaap }
96123879Sjaap
96223879Sjaap
casesy()96323901Sjaap casesy() /* call system */
96423901Sjaap {
96523879Sjaap char sybuf[NTM];
96623879Sjaap int i;
96723879Sjaap
96823879Sjaap lgf++;
96923879Sjaap copyf++;
97023879Sjaap skip();
97123879Sjaap for (i = 0; i < NTM - 2; i++)
97223879Sjaap if ((sybuf[i] = getch()) == '\n')
97323879Sjaap break;
97423879Sjaap sybuf[i] = 0;
97523879Sjaap system(sybuf);
97623879Sjaap copyf--;
97723901Sjaap lgf--;
97823879Sjaap }
97923879Sjaap
98023879Sjaap
getpn(a)98123879Sjaap getpn(a)
98223879Sjaap register char *a;
98323879Sjaap {
98423879Sjaap register int n, neg;
98523879Sjaap
98623879Sjaap if (*a == 0)
98723879Sjaap return;
98823879Sjaap neg = 0;
98923879Sjaap for ( ; *a; a++)
99023879Sjaap switch (*a) {
99123879Sjaap case '+':
99223879Sjaap case ',':
99323879Sjaap continue;
99423879Sjaap case '-':
99523879Sjaap neg = 1;
99623879Sjaap continue;
99723879Sjaap default:
99823879Sjaap n = 0;
99923879Sjaap if (isdigit(*a)) {
100023879Sjaap do
100123879Sjaap n = 10 * n + *a++ - '0';
100223879Sjaap while (isdigit(*a));
100323879Sjaap a--;
100423879Sjaap } else
100523879Sjaap n = 9999;
100623879Sjaap *pnp++ = neg ? -n : n;
100723879Sjaap neg = 0;
100823879Sjaap if (pnp >= &pnlist[NPN-2]) {
100923901Sjaap errprint("too many page numbers");
101023879Sjaap done3(-3);
101123879Sjaap }
101223879Sjaap }
101323879Sjaap if (neg)
101423879Sjaap *pnp++ = -9999;
101523879Sjaap *pnp = -32767;
101623879Sjaap print = 0;
101723879Sjaap pnp = pnlist;
101823879Sjaap if (*pnp != -32767)
101923879Sjaap chkpn();
102023879Sjaap }
102123879Sjaap
102223879Sjaap
setrpt()102323879Sjaap setrpt()
102423879Sjaap {
102523879Sjaap tchar i, j;
102623879Sjaap
102723879Sjaap copyf++;
102823879Sjaap raw++;
102923879Sjaap i = getch0();
103023879Sjaap copyf--;
103123879Sjaap raw--;
103223879Sjaap if (i < 0 || cbits(j = getch0()) == RPT)
103323879Sjaap return;
103423901Sjaap i &= BYTEMASK;
103523901Sjaap while (i>0 && pbp < &pbbuf[NC-3]) {
103623901Sjaap i--;
103723901Sjaap *pbp++ = j;
103823901Sjaap }
103923879Sjaap }
1040