13e12c5d1SDavid du Colombier /*
23e12c5d1SDavid du Colombier * n1.c
33e12c5d1SDavid du Colombier *
43e12c5d1SDavid du Colombier * consume options, initialization, main loop,
53e12c5d1SDavid du Colombier * input routines, escape function calling
63e12c5d1SDavid du Colombier */
73e12c5d1SDavid du Colombier
83e12c5d1SDavid du Colombier #include "tdef.h"
93e12c5d1SDavid du Colombier #include "fns.h"
103e12c5d1SDavid du Colombier #include "ext.h"
11219b2ee8SDavid du Colombier #include "dwbinit.h"
123e12c5d1SDavid du Colombier
133e12c5d1SDavid du Colombier #include <setjmp.h>
143e12c5d1SDavid du Colombier #include <time.h>
153e12c5d1SDavid du Colombier
16219b2ee8SDavid du Colombier char *Version = "March 11, 1994";
17219b2ee8SDavid du Colombier
18219b2ee8SDavid du Colombier #ifndef DWBVERSION
19219b2ee8SDavid du Colombier #define DWBVERSION "???"
20219b2ee8SDavid du Colombier #endif
21219b2ee8SDavid du Colombier
22219b2ee8SDavid du Colombier char *DWBfontdir = FONTDIR;
23219b2ee8SDavid du Colombier char *DWBntermdir = NTERMDIR;
24219b2ee8SDavid du Colombier char *DWBalthyphens = ALTHYPHENS;
25219b2ee8SDavid du Colombier char *DWBhomedir = "";
26219b2ee8SDavid du Colombier
27219b2ee8SDavid du Colombier dwbinit dwbpaths[] = {
28219b2ee8SDavid du Colombier &DWBfontdir, NULL, 0,
29219b2ee8SDavid du Colombier &DWBntermdir, NULL, 0,
30219b2ee8SDavid du Colombier &DWBalthyphens, NULL, 0,
31219b2ee8SDavid du Colombier &DWBhomedir, NULL, 0,
32219b2ee8SDavid du Colombier NULL, nextf, NS,
33219b2ee8SDavid du Colombier NULL, NULL, 0
34219b2ee8SDavid du Colombier };
35219b2ee8SDavid du Colombier
363e12c5d1SDavid du Colombier int TROFF = 1; /* assume we started in troff... */
373e12c5d1SDavid du Colombier
383e12c5d1SDavid du Colombier jmp_buf sjbuf;
393e12c5d1SDavid du Colombier Offset ipl[NSO];
403e12c5d1SDavid du Colombier
413e12c5d1SDavid du Colombier static FILE *ifile = stdin;
423e12c5d1SDavid du Colombier static FILE *ifl[NSO]; /* open input file pointers */
433e12c5d1SDavid du Colombier char cfname[NSO+1][NS] = { "stdin" }; /* file name stack */
443e12c5d1SDavid du Colombier int cfline[NSO]; /* input line count stack */
453e12c5d1SDavid du Colombier char *progname; /* program name (troff or nroff) */
463e12c5d1SDavid du Colombier
47219b2ee8SDavid du Colombier int trace = 0; /* tracing mode: default off */
48219b2ee8SDavid du Colombier int trace1 = 0;
493e12c5d1SDavid du Colombier
main(int argc,char * argv[])503e12c5d1SDavid du Colombier main(int argc, char *argv[])
513e12c5d1SDavid du Colombier {
523e12c5d1SDavid du Colombier char *p;
533e12c5d1SDavid du Colombier int j;
543e12c5d1SDavid du Colombier Tchar i;
553e12c5d1SDavid du Colombier char buf[100];
563e12c5d1SDavid du Colombier
57219b2ee8SDavid du Colombier buf[0] = '\0'; /* make sure it's empty (silly 3b2) */
583e12c5d1SDavid du Colombier progname = argv[0];
59219b2ee8SDavid du Colombier if ((p = strrchr(progname, '/')) == NULL)
60219b2ee8SDavid du Colombier p = progname;
61219b2ee8SDavid du Colombier else
62219b2ee8SDavid du Colombier p++;
63219b2ee8SDavid du Colombier DWBinit(progname, dwbpaths);
64219b2ee8SDavid du Colombier if (strcmp(p, "nroff") == 0)
653e12c5d1SDavid du Colombier TROFF = 0;
66219b2ee8SDavid du Colombier #ifdef UNICODE
673e12c5d1SDavid du Colombier alphabet = 128; /* unicode for plan 9 */
68219b2ee8SDavid du Colombier #endif /*UNICODE*/
69219b2ee8SDavid du Colombier mnspace();
70219b2ee8SDavid du Colombier nnspace();
713e12c5d1SDavid du Colombier mrehash();
723e12c5d1SDavid du Colombier nrehash();
73219b2ee8SDavid du Colombier numtabp[NL].val = -1;
743e12c5d1SDavid du Colombier
753e12c5d1SDavid du Colombier while (--argc > 0 && (++argv)[0][0] == '-')
763e12c5d1SDavid du Colombier switch (argv[0][1]) {
773e12c5d1SDavid du Colombier
783e12c5d1SDavid du Colombier case 'N': /* ought to be used first... */
793e12c5d1SDavid du Colombier TROFF = 0;
803e12c5d1SDavid du Colombier break;
813e12c5d1SDavid du Colombier case 'd':
823e12c5d1SDavid du Colombier fprintf(stderr, "troff/nroff version %s\n", Version);
833e12c5d1SDavid du Colombier break;
843e12c5d1SDavid du Colombier case 'F': /* switch font tables from default */
853e12c5d1SDavid du Colombier if (argv[0][2] != '\0') {
863e12c5d1SDavid du Colombier strcpy(termtab, &argv[0][2]);
873e12c5d1SDavid du Colombier strcpy(fontdir, &argv[0][2]);
883e12c5d1SDavid du Colombier } else {
893e12c5d1SDavid du Colombier argv++; argc--;
903e12c5d1SDavid du Colombier strcpy(termtab, argv[0]);
913e12c5d1SDavid du Colombier strcpy(fontdir, argv[0]);
923e12c5d1SDavid du Colombier }
933e12c5d1SDavid du Colombier break;
943e12c5d1SDavid du Colombier case 0:
953e12c5d1SDavid du Colombier goto start;
963e12c5d1SDavid du Colombier case 'i':
973e12c5d1SDavid du Colombier stdi++;
983e12c5d1SDavid du Colombier break;
993e12c5d1SDavid du Colombier case 'n':
1003e12c5d1SDavid du Colombier npn = atoi(&argv[0][2]);
1013e12c5d1SDavid du Colombier break;
1023e12c5d1SDavid du Colombier case 'u': /* set emboldening amount */
1033e12c5d1SDavid du Colombier bdtab[3] = atoi(&argv[0][2]);
1043e12c5d1SDavid du Colombier if (bdtab[3] < 0 || bdtab[3] > 50)
1053e12c5d1SDavid du Colombier bdtab[3] = 0;
1063e12c5d1SDavid du Colombier break;
1073e12c5d1SDavid du Colombier case 's':
1083e12c5d1SDavid du Colombier if (!(stop = atoi(&argv[0][2])))
1093e12c5d1SDavid du Colombier stop++;
1103e12c5d1SDavid du Colombier break;
1113e12c5d1SDavid du Colombier case 'r':
1123e12c5d1SDavid du Colombier sprintf(buf + strlen(buf), ".nr %c %s\n",
1133e12c5d1SDavid du Colombier argv[0][2], &argv[0][3]);
114219b2ee8SDavid du Colombier /* not yet cpushback(buf);*/
1153e12c5d1SDavid du Colombier /* dotnr(&argv[0][2], &argv[0][3]); */
1163e12c5d1SDavid du Colombier break;
1173e12c5d1SDavid du Colombier case 'm':
1183e12c5d1SDavid du Colombier if (mflg++ >= NMF) {
1193e12c5d1SDavid du Colombier ERROR "Too many macro packages: %s", argv[0] WARN;
1203e12c5d1SDavid du Colombier break;
1213e12c5d1SDavid du Colombier }
1223e12c5d1SDavid du Colombier strcpy(mfiles[nmfi], nextf);
1233e12c5d1SDavid du Colombier strcat(mfiles[nmfi++], &argv[0][2]);
1243e12c5d1SDavid du Colombier break;
1253e12c5d1SDavid du Colombier case 'o':
1263e12c5d1SDavid du Colombier getpn(&argv[0][2]);
1273e12c5d1SDavid du Colombier break;
1283e12c5d1SDavid du Colombier case 'T':
1293e12c5d1SDavid du Colombier strcpy(devname, &argv[0][2]);
1303e12c5d1SDavid du Colombier dotT++;
1313e12c5d1SDavid du Colombier break;
1323e12c5d1SDavid du Colombier case 'a':
1333e12c5d1SDavid du Colombier ascii = 1;
1343e12c5d1SDavid du Colombier break;
1353e12c5d1SDavid du Colombier case 'h':
1363e12c5d1SDavid du Colombier hflg++;
1373e12c5d1SDavid du Colombier break;
1383e12c5d1SDavid du Colombier case 'e':
1393e12c5d1SDavid du Colombier eqflg++;
1403e12c5d1SDavid du Colombier break;
1413e12c5d1SDavid du Colombier case 'q':
1423e12c5d1SDavid du Colombier quiet++;
1433e12c5d1SDavid du Colombier save_tty();
1443e12c5d1SDavid du Colombier break;
145219b2ee8SDavid du Colombier case 'V':
146219b2ee8SDavid du Colombier fprintf(stdout, "%croff: DWB %s\n",
147219b2ee8SDavid du Colombier TROFF ? 't' : 'n', DWBVERSION);
148219b2ee8SDavid du Colombier exit(0);
149219b2ee8SDavid du Colombier case 't':
150219b2ee8SDavid du Colombier if (argv[0][2] != '\0')
151219b2ee8SDavid du Colombier trace = trace1 = argv[0][2];
152219b2ee8SDavid du Colombier break; /* for the sake of compatibility */
1533e12c5d1SDavid du Colombier default:
1543e12c5d1SDavid du Colombier ERROR "unknown option %s", argv[0] WARN;
1553e12c5d1SDavid du Colombier done(02);
1563e12c5d1SDavid du Colombier }
1573e12c5d1SDavid du Colombier
1583e12c5d1SDavid du Colombier start:
159219b2ee8SDavid du Colombier /*
160219b2ee8SDavid du Colombier * cpushback maintains a LIFO, so push pack the -r arguments
161219b2ee8SDavid du Colombier * in reverse order to maintain a FIFO in case someone did -rC1 -rC3
162219b2ee8SDavid du Colombier */
163219b2ee8SDavid du Colombier if (buf[0]) {
164219b2ee8SDavid du Colombier char *p = buf;
165219b2ee8SDavid du Colombier while(*p++)
166219b2ee8SDavid du Colombier ;
167219b2ee8SDavid du Colombier while(p > buf) {
168219b2ee8SDavid du Colombier while(strncmp(p, ".nr", 3) != 0)
169219b2ee8SDavid du Colombier p--;
170219b2ee8SDavid du Colombier cpushback(p);
171219b2ee8SDavid du Colombier *p-- = '\0';
172219b2ee8SDavid du Colombier }
173219b2ee8SDavid du Colombier }
1743e12c5d1SDavid du Colombier argp = argv;
1753e12c5d1SDavid du Colombier rargc = argc;
1763e12c5d1SDavid du Colombier nmfi = 0;
1773e12c5d1SDavid du Colombier init2();
1783e12c5d1SDavid du Colombier setjmp(sjbuf);
1793e12c5d1SDavid du Colombier loop:
1803e12c5d1SDavid du Colombier copyf = lgf = nb = nflush = nlflg = 0;
181219b2ee8SDavid du Colombier if (ip && rbf0(ip) == 0 && ejf && frame->pframe <= ejl && dip == d) {
1823e12c5d1SDavid du Colombier nflush++;
1833e12c5d1SDavid du Colombier trap = 0;
1843e12c5d1SDavid du Colombier eject((Stack *)0);
1853e12c5d1SDavid du Colombier goto loop;
1863e12c5d1SDavid du Colombier }
1873e12c5d1SDavid du Colombier i = getch();
1883e12c5d1SDavid du Colombier if (pendt)
1893e12c5d1SDavid du Colombier goto Lt;
1903e12c5d1SDavid du Colombier if ((j = cbits(i)) == XPAR) {
1913e12c5d1SDavid du Colombier copyf++;
1923e12c5d1SDavid du Colombier tflg++;
1933e12c5d1SDavid du Colombier while (cbits(i) != '\n')
1943e12c5d1SDavid du Colombier pchar(i = getch());
1953e12c5d1SDavid du Colombier tflg = 0;
196*14f51593SDavid du Colombier copyf--; /* pointless */
1973e12c5d1SDavid du Colombier goto loop;
1983e12c5d1SDavid du Colombier }
1993e12c5d1SDavid du Colombier if (j == cc || j == c2) {
2003e12c5d1SDavid du Colombier if (j == c2)
2013e12c5d1SDavid du Colombier nb++;
2023e12c5d1SDavid du Colombier copyf++;
2033e12c5d1SDavid du Colombier while ((j = cbits(i = getch())) == ' ' || j == '\t')
2043e12c5d1SDavid du Colombier ;
2053e12c5d1SDavid du Colombier ch = i;
2063e12c5d1SDavid du Colombier copyf--;
2073e12c5d1SDavid du Colombier control(getrq(), 1);
2083e12c5d1SDavid du Colombier flushi();
2093e12c5d1SDavid du Colombier goto loop;
2103e12c5d1SDavid du Colombier }
2113e12c5d1SDavid du Colombier Lt:
2123e12c5d1SDavid du Colombier ch = i;
2133e12c5d1SDavid du Colombier text();
2143e12c5d1SDavid du Colombier if (nlflg)
215219b2ee8SDavid du Colombier numtabp[HP].val = 0;
2163e12c5d1SDavid du Colombier goto loop;
2173e12c5d1SDavid du Colombier }
2183e12c5d1SDavid du Colombier
2193e12c5d1SDavid du Colombier
2203e12c5d1SDavid du Colombier
init2(void)2213e12c5d1SDavid du Colombier void init2(void)
2223e12c5d1SDavid du Colombier {
2233e12c5d1SDavid du Colombier int i;
2243e12c5d1SDavid du Colombier char buf[100];
2253e12c5d1SDavid du Colombier
2263e12c5d1SDavid du Colombier for (i = NTRTAB; --i; )
2273e12c5d1SDavid du Colombier trtab[i] = i;
2283e12c5d1SDavid du Colombier trtab[UNPAD] = ' ';
2293e12c5d1SDavid du Colombier iflg = 0;
2303e12c5d1SDavid du Colombier obufp = obuf;
2313e12c5d1SDavid du Colombier if (TROFF)
2323e12c5d1SDavid du Colombier t_ptinit();
2333e12c5d1SDavid du Colombier else
2343e12c5d1SDavid du Colombier n_ptinit();
2353e12c5d1SDavid du Colombier mchbits();
2363e12c5d1SDavid du Colombier cvtime();
237219b2ee8SDavid du Colombier numtabp[PID].val = getpid();
238219b2ee8SDavid du Colombier numtabp[HP].val = init = 0;
239219b2ee8SDavid du Colombier numtabp[NL].val = -1;
2403e12c5d1SDavid du Colombier nfo = 0;
2413e12c5d1SDavid du Colombier copyf = raw = 0;
2423e12c5d1SDavid du Colombier sprintf(buf, ".ds .T %s\n", devname);
2433e12c5d1SDavid du Colombier cpushback(buf);
244219b2ee8SDavid du Colombier sprintf(buf, ".ds .P %s\n", DWBhomedir);
245219b2ee8SDavid du Colombier cpushback(buf);
246219b2ee8SDavid du Colombier numtabp[CD].val = -1; /* compensation */
2473e12c5d1SDavid du Colombier nx = mflg;
2483e12c5d1SDavid du Colombier frame = stk = (Stack *)setbrk(STACKSIZE);
2493e12c5d1SDavid du Colombier dip = &d[0];
2503e12c5d1SDavid du Colombier nxf = frame + 1;
2513e12c5d1SDavid du Colombier for (i = 1; i < NEV; i++) /* propagate the environment */
2523e12c5d1SDavid du Colombier envcopy(&env[i], &env[0]);
253219b2ee8SDavid du Colombier for (i = 0; i < NEV; i++) {
254219b2ee8SDavid du Colombier if ((env[i]._word._bufp = (Tchar *)calloc(WDSIZE, sizeof(Tchar))) == NULL) {
255219b2ee8SDavid du Colombier ERROR "not enough room for word buffers" WARN;
256219b2ee8SDavid du Colombier done2(1);
257219b2ee8SDavid du Colombier }
258219b2ee8SDavid du Colombier env[i]._word._size = WDSIZE;
259219b2ee8SDavid du Colombier if ((env[i]._line._bufp = (Tchar *)calloc(LNSIZE, sizeof(Tchar))) == NULL) {
260219b2ee8SDavid du Colombier ERROR "not enough room for line buffers" WARN;
261219b2ee8SDavid du Colombier done2(1);
262219b2ee8SDavid du Colombier }
263219b2ee8SDavid du Colombier env[i]._line._size = LNSIZE;
264219b2ee8SDavid du Colombier }
265219b2ee8SDavid du Colombier if ((oline = (Tchar *)calloc(OLNSIZE, sizeof(Tchar))) == NULL) {
266219b2ee8SDavid du Colombier ERROR "not enough room for line buffers" WARN;
267219b2ee8SDavid du Colombier done2(1);
268219b2ee8SDavid du Colombier }
269219b2ee8SDavid du Colombier olinep = oline;
270219b2ee8SDavid du Colombier olnsize = OLNSIZE;
2713e12c5d1SDavid du Colombier blockinit();
2723e12c5d1SDavid du Colombier }
2733e12c5d1SDavid du Colombier
cvtime(void)2743e12c5d1SDavid du Colombier void cvtime(void)
2753e12c5d1SDavid du Colombier {
2763e12c5d1SDavid du Colombier long tt;
2773e12c5d1SDavid du Colombier struct tm *ltime;
2783e12c5d1SDavid du Colombier
2793e12c5d1SDavid du Colombier time(&tt);
2803e12c5d1SDavid du Colombier ltime = localtime(&tt);
2817dd7cddfSDavid du Colombier numtabp[YR].val = ltime->tm_year % 100;
2827dd7cddfSDavid du Colombier numtabp[YR].fmt = 2;
283219b2ee8SDavid du Colombier numtabp[MO].val = ltime->tm_mon + 1; /* troff uses 1..12 */
284219b2ee8SDavid du Colombier numtabp[DY].val = ltime->tm_mday;
285219b2ee8SDavid du Colombier numtabp[DW].val = ltime->tm_wday + 1; /* troff uses 1..7 */
2863e12c5d1SDavid du Colombier }
2873e12c5d1SDavid du Colombier
2883e12c5d1SDavid du Colombier
2893e12c5d1SDavid du Colombier
2903e12c5d1SDavid du Colombier char errbuf[200];
2913e12c5d1SDavid du Colombier
errprint(void)2923e12c5d1SDavid du Colombier void errprint(void) /* error message printer */
2933e12c5d1SDavid du Colombier {
294219b2ee8SDavid du Colombier int savecd = numtabp[CD].val;
295219b2ee8SDavid du Colombier
296219b2ee8SDavid du Colombier if (!nlflg)
297219b2ee8SDavid du Colombier numtabp[CD].val++;
298219b2ee8SDavid du Colombier
2993e12c5d1SDavid du Colombier fprintf(stderr, "%s: ", progname);
3003e12c5d1SDavid du Colombier fputs(errbuf, stderr);
301219b2ee8SDavid du Colombier if (cfname[ifi][0])
3027dd7cddfSDavid du Colombier fprintf(stderr, "; %s:%d", cfname[ifi], numtabp[CD].val);
3033e12c5d1SDavid du Colombier fputs("\n", stderr);
304219b2ee8SDavid du Colombier if (cfname[ifi][0])
3053e12c5d1SDavid du Colombier stackdump();
306219b2ee8SDavid du Colombier numtabp[CD].val = savecd;
3073e12c5d1SDavid du Colombier }
3083e12c5d1SDavid du Colombier
3093e12c5d1SDavid du Colombier
control(int a,int b)3103e12c5d1SDavid du Colombier int control(int a, int b)
3113e12c5d1SDavid du Colombier {
312219b2ee8SDavid du Colombier int j, k;
313219b2ee8SDavid du Colombier extern Contab *contabp;
3143e12c5d1SDavid du Colombier
315219b2ee8SDavid du Colombier numerr.type = RQERR;
316219b2ee8SDavid du Colombier numerr.req = a;
3173e12c5d1SDavid du Colombier if (a == 0 || (j = findmn(a)) == -1)
3183e12c5d1SDavid du Colombier return(0);
319219b2ee8SDavid du Colombier if (contabp[j].f == 0) {
320219b2ee8SDavid du Colombier if (trace & TRMAC)
321219b2ee8SDavid du Colombier fprintf(stderr, "invoke macro %s\n", unpair(a));
322219b2ee8SDavid du Colombier if (dip != d)
323219b2ee8SDavid du Colombier for (k = dilev; k; k--)
324219b2ee8SDavid du Colombier if (d[k].curd == a) {
325219b2ee8SDavid du Colombier ERROR "diversion %s invokes itself during diversion",
326219b2ee8SDavid du Colombier unpair(a) WARN;
327219b2ee8SDavid du Colombier edone(0100);
328219b2ee8SDavid du Colombier }
3293e12c5d1SDavid du Colombier nxf->nargs = 0;
3303e12c5d1SDavid du Colombier if (b)
3313e12c5d1SDavid du Colombier collect();
3323e12c5d1SDavid du Colombier flushi();
333219b2ee8SDavid du Colombier return pushi(contabp[j].mx, a); /* BUG??? all that matters is 0/!0 */
3343e12c5d1SDavid du Colombier }
335219b2ee8SDavid du Colombier if (b) {
336219b2ee8SDavid du Colombier if (trace & TRREQ)
337219b2ee8SDavid du Colombier fprintf(stderr, "invoke request %s\n", unpair(a));
338219b2ee8SDavid du Colombier (*contabp[j].f)();
339219b2ee8SDavid du Colombier }
3403e12c5d1SDavid du Colombier return(0);
3413e12c5d1SDavid du Colombier }
3423e12c5d1SDavid du Colombier
casept(void)343219b2ee8SDavid du Colombier void casept(void)
344219b2ee8SDavid du Colombier {
345219b2ee8SDavid du Colombier int i;
346219b2ee8SDavid du Colombier
347219b2ee8SDavid du Colombier noscale++;
348219b2ee8SDavid du Colombier if (skip())
349219b2ee8SDavid du Colombier i = trace1;
350219b2ee8SDavid du Colombier else {
351219b2ee8SDavid du Colombier i = max(inumb(&trace), 0);
352219b2ee8SDavid du Colombier if (nonumb)
353219b2ee8SDavid du Colombier i = trace1;
354219b2ee8SDavid du Colombier }
355219b2ee8SDavid du Colombier trace1 = trace;
356219b2ee8SDavid du Colombier trace = i;
357219b2ee8SDavid du Colombier noscale = 0;
358219b2ee8SDavid du Colombier }
359219b2ee8SDavid du Colombier
3603e12c5d1SDavid du Colombier
getrq(void)3613e12c5d1SDavid du Colombier int getrq(void)
3623e12c5d1SDavid du Colombier {
3633e12c5d1SDavid du Colombier int i, j;
3643e12c5d1SDavid du Colombier
3653e12c5d1SDavid du Colombier if ((i = getach()) == 0 || (j = getach()) == 0)
3663e12c5d1SDavid du Colombier goto rtn;
3673e12c5d1SDavid du Colombier i = PAIR(i, j);
3683e12c5d1SDavid du Colombier rtn:
3693e12c5d1SDavid du Colombier return(i);
3703e12c5d1SDavid du Colombier }
3713e12c5d1SDavid du Colombier
3723e12c5d1SDavid du Colombier /*
3733e12c5d1SDavid du Colombier * table encodes some special characters, to speed up tests
3743e12c5d1SDavid du Colombier * in getch, viz FLSS, RPT, f, \b, \n, fc, tabch, ldrch
3753e12c5d1SDavid du Colombier */
3763e12c5d1SDavid du Colombier
3773e12c5d1SDavid du Colombier char gchtab[NCHARS] = {
3783e12c5d1SDavid du Colombier 000,004,000,000,010,000,000,000, /* fc, ldr */
3793e12c5d1SDavid du Colombier 001,002,001,000,001,000,000,000, /* \b, tab, nl, RPT */
3803e12c5d1SDavid du Colombier 000,000,000,000,000,000,000,000,
3813e12c5d1SDavid du Colombier 000,001,000,001,000,000,000,000, /* FLSS, ESC */
3823e12c5d1SDavid du Colombier 000,000,000,000,000,000,000,000,
3833e12c5d1SDavid du Colombier 000,000,000,000,000,000,000,000,
3843e12c5d1SDavid du Colombier 000,000,000,000,000,000,000,000,
3853e12c5d1SDavid du Colombier 000,000,000,000,000,000,000,000,
3863e12c5d1SDavid du Colombier 000,000,000,000,000,000,000,000,
3873e12c5d1SDavid du Colombier 000,000,000,000,000,000,000,000,
3883e12c5d1SDavid du Colombier 000,000,000,000,000,000,000,000,
3893e12c5d1SDavid du Colombier 000,000,000,000,000,000,000,000,
3903e12c5d1SDavid du Colombier 000,000,000,000,000,000,001,000, /* f */
3913e12c5d1SDavid du Colombier 000,000,000,000,000,000,000,000,
3923e12c5d1SDavid du Colombier 000,000,000,000,000,000,000,000,
3933e12c5d1SDavid du Colombier 000,000,000,000,000,000,000,000,
3943e12c5d1SDavid du Colombier };
3953e12c5d1SDavid du Colombier
realcbits(Tchar c)3963e12c5d1SDavid du Colombier int realcbits(Tchar c) /* return character bits, or MOTCH if motion */
3973e12c5d1SDavid du Colombier {
3983e12c5d1SDavid du Colombier if (ismot(c))
3993e12c5d1SDavid du Colombier return MOTCH;
4003e12c5d1SDavid du Colombier else
4013e12c5d1SDavid du Colombier return c & 0xFFFF;
4023e12c5d1SDavid du Colombier }
4033e12c5d1SDavid du Colombier
getch(void)4043e12c5d1SDavid du Colombier Tchar getch(void)
4053e12c5d1SDavid du Colombier {
4063e12c5d1SDavid du Colombier int k;
4073e12c5d1SDavid du Colombier Tchar i, j;
4083e12c5d1SDavid du Colombier
4093e12c5d1SDavid du Colombier g0:
4103e12c5d1SDavid du Colombier if (ch) {
4113e12c5d1SDavid du Colombier i = ch;
4123e12c5d1SDavid du Colombier if (cbits(i) == '\n')
4133e12c5d1SDavid du Colombier nlflg++;
4143e12c5d1SDavid du Colombier ch = 0;
4153e12c5d1SDavid du Colombier return(i);
4163e12c5d1SDavid du Colombier }
4173e12c5d1SDavid du Colombier
4183e12c5d1SDavid du Colombier if (nlflg)
4193e12c5d1SDavid du Colombier return('\n');
4203e12c5d1SDavid du Colombier i = getch0();
4213e12c5d1SDavid du Colombier if (ismot(i))
4223e12c5d1SDavid du Colombier return(i);
4233e12c5d1SDavid du Colombier k = cbits(i);
4243e12c5d1SDavid du Colombier if (k >= sizeof(gchtab)/sizeof(gchtab[0]) || gchtab[k] == 0) /* nothing special */
4253e12c5d1SDavid du Colombier return(i);
4263e12c5d1SDavid du Colombier if (k != ESC) {
4273e12c5d1SDavid du Colombier if (k == '\n') {
4283e12c5d1SDavid du Colombier nlflg++;
4293e12c5d1SDavid du Colombier if (ip == 0)
430219b2ee8SDavid du Colombier numtabp[CD].val++; /* line number */
4313e12c5d1SDavid du Colombier return(k);
4323e12c5d1SDavid du Colombier }
4333e12c5d1SDavid du Colombier if (k == FLSS) {
4343e12c5d1SDavid du Colombier copyf++;
4353e12c5d1SDavid du Colombier raw++;
4363e12c5d1SDavid du Colombier i = getch0();
4373e12c5d1SDavid du Colombier if (!fi)
4383e12c5d1SDavid du Colombier flss = i;
4393e12c5d1SDavid du Colombier copyf--;
4403e12c5d1SDavid du Colombier raw--;
4413e12c5d1SDavid du Colombier goto g0;
4423e12c5d1SDavid du Colombier }
4433e12c5d1SDavid du Colombier if (k == RPT) {
4443e12c5d1SDavid du Colombier setrpt();
4453e12c5d1SDavid du Colombier goto g0;
4463e12c5d1SDavid du Colombier }
4473e12c5d1SDavid du Colombier if (!copyf) {
4483e12c5d1SDavid du Colombier if (k == 'f' && lg && !lgf) {
4493e12c5d1SDavid du Colombier i = getlg(i);
4503e12c5d1SDavid du Colombier return(i);
4513e12c5d1SDavid du Colombier }
4523e12c5d1SDavid du Colombier if (k == fc || k == tabch || k == ldrch) {
4533e12c5d1SDavid du Colombier if ((i = setfield(k)) == 0)
4543e12c5d1SDavid du Colombier goto g0;
4553e12c5d1SDavid du Colombier else
4563e12c5d1SDavid du Colombier return(i);
4573e12c5d1SDavid du Colombier }
4583e12c5d1SDavid du Colombier if (k == '\b') {
4593e12c5d1SDavid du Colombier i = makem(-width(' ' | chbits));
4603e12c5d1SDavid du Colombier return(i);
4613e12c5d1SDavid du Colombier }
4623e12c5d1SDavid du Colombier }
4633e12c5d1SDavid du Colombier return(i);
4643e12c5d1SDavid du Colombier }
4653e12c5d1SDavid du Colombier
4663e12c5d1SDavid du Colombier k = cbits(j = getch0());
4673e12c5d1SDavid du Colombier if (ismot(j))
4683e12c5d1SDavid du Colombier return(j);
4693e12c5d1SDavid du Colombier
4703e12c5d1SDavid du Colombier switch (k) {
4713e12c5d1SDavid du Colombier case 'n': /* number register */
4723e12c5d1SDavid du Colombier setn();
4733e12c5d1SDavid du Colombier goto g0;
4743e12c5d1SDavid du Colombier case '$': /* argument indicator */
4753e12c5d1SDavid du Colombier seta();
4763e12c5d1SDavid du Colombier goto g0;
4773e12c5d1SDavid du Colombier case '*': /* string indicator */
4783e12c5d1SDavid du Colombier setstr();
4793e12c5d1SDavid du Colombier goto g0;
4803e12c5d1SDavid du Colombier case '{': /* LEFT */
4813e12c5d1SDavid du Colombier i = LEFT;
4823e12c5d1SDavid du Colombier goto gx;
4833e12c5d1SDavid du Colombier case '}': /* RIGHT */
4843e12c5d1SDavid du Colombier i = RIGHT;
4853e12c5d1SDavid du Colombier goto gx;
4863e12c5d1SDavid du Colombier case '"': /* comment */
4873e12c5d1SDavid du Colombier while (cbits(i = getch0()) != '\n')
4883e12c5d1SDavid du Colombier ;
4893e12c5d1SDavid du Colombier if (ip == 0)
490219b2ee8SDavid du Colombier numtabp[CD].val++; /* line number */
491219b2ee8SDavid du Colombier nlflg++;
4923e12c5d1SDavid du Colombier return(i);
4933e12c5d1SDavid du Colombier
4943e12c5d1SDavid du Colombier /* experiment: put it here instead of copy mode */
4953e12c5d1SDavid du Colombier case '(': /* special char name \(xx */
4963e12c5d1SDavid du Colombier case 'C': /* \C'...' */
4973e12c5d1SDavid du Colombier if ((i = setch(k)) == 0)
4983e12c5d1SDavid du Colombier goto g0;
4993e12c5d1SDavid du Colombier goto gx;
5003e12c5d1SDavid du Colombier
5013e12c5d1SDavid du Colombier case ESC: /* double backslash */
5023e12c5d1SDavid du Colombier i = eschar;
5033e12c5d1SDavid du Colombier goto gx;
5043e12c5d1SDavid du Colombier case 'e': /* printable version of current eschar */
5053e12c5d1SDavid du Colombier i = PRESC;
5063e12c5d1SDavid du Colombier goto gx;
5073e12c5d1SDavid du Colombier case '\n': /* concealed newline */
508219b2ee8SDavid du Colombier numtabp[CD].val++;
5093e12c5d1SDavid du Colombier goto g0;
5103e12c5d1SDavid du Colombier case ' ': /* unpaddable space */
5113e12c5d1SDavid du Colombier i = UNPAD;
5123e12c5d1SDavid du Colombier goto gx;
5133e12c5d1SDavid du Colombier case '\'': /* \(aa */
5143e12c5d1SDavid du Colombier i = ACUTE;
5153e12c5d1SDavid du Colombier goto gx;
5163e12c5d1SDavid du Colombier case '`': /* \(ga */
5173e12c5d1SDavid du Colombier i = GRAVE;
5183e12c5d1SDavid du Colombier goto gx;
5193e12c5d1SDavid du Colombier case '_': /* \(ul */
5203e12c5d1SDavid du Colombier i = UNDERLINE;
5213e12c5d1SDavid du Colombier goto gx;
5223e12c5d1SDavid du Colombier case '-': /* current font minus */
5233e12c5d1SDavid du Colombier i = MINUS;
5243e12c5d1SDavid du Colombier goto gx;
5253e12c5d1SDavid du Colombier case '&': /* filler */
5263e12c5d1SDavid du Colombier i = FILLER;
5273e12c5d1SDavid du Colombier goto gx;
5283e12c5d1SDavid du Colombier case 'c': /* to be continued */
5293e12c5d1SDavid du Colombier i = CONT;
5303e12c5d1SDavid du Colombier goto gx;
5313e12c5d1SDavid du Colombier case '!': /* transparent indicator */
5323e12c5d1SDavid du Colombier i = XPAR;
5333e12c5d1SDavid du Colombier goto gx;
5343e12c5d1SDavid du Colombier case 't': /* tab */
5353e12c5d1SDavid du Colombier i = '\t';
5363e12c5d1SDavid du Colombier return(i);
5373e12c5d1SDavid du Colombier case 'a': /* leader (SOH) */
5383e12c5d1SDavid du Colombier /* old: *pbp++ = LEADER; goto g0; */
5393e12c5d1SDavid du Colombier i = LEADER;
5403e12c5d1SDavid du Colombier return i;
5413e12c5d1SDavid du Colombier case '%': /* ohc */
5423e12c5d1SDavid du Colombier i = OHC;
5433e12c5d1SDavid du Colombier return(i);
5443e12c5d1SDavid du Colombier case 'g': /* return format of a number register */
5453e12c5d1SDavid du Colombier setaf(); /* should this really be in copy mode??? */
5463e12c5d1SDavid du Colombier goto g0;
5473e12c5d1SDavid du Colombier case '.': /* . */
5483e12c5d1SDavid du Colombier i = '.';
5493e12c5d1SDavid du Colombier gx:
5503e12c5d1SDavid du Colombier setsfbits(i, sfbits(j));
5513e12c5d1SDavid du Colombier return(i);
5523e12c5d1SDavid du Colombier }
5533e12c5d1SDavid du Colombier if (copyf) {
5543e12c5d1SDavid du Colombier *pbp++ = j;
5553e12c5d1SDavid du Colombier return(eschar);
5563e12c5d1SDavid du Colombier }
5573e12c5d1SDavid du Colombier switch (k) {
5583e12c5d1SDavid du Colombier
5593e12c5d1SDavid du Colombier case 'f': /* font indicator */
5603e12c5d1SDavid du Colombier setfont(0);
5613e12c5d1SDavid du Colombier goto g0;
5623e12c5d1SDavid du Colombier case 's': /* size indicator */
5633e12c5d1SDavid du Colombier setps();
5643e12c5d1SDavid du Colombier goto g0;
5653e12c5d1SDavid du Colombier case 'v': /* vert mot */
566219b2ee8SDavid du Colombier numerr.type = numerr.escarg = 0; numerr.esc = k;
5673e12c5d1SDavid du Colombier if (i = vmot()) {
5683e12c5d1SDavid du Colombier return(i);
5693e12c5d1SDavid du Colombier }
5703e12c5d1SDavid du Colombier goto g0;
5713e12c5d1SDavid du Colombier case 'h': /* horiz mot */
572219b2ee8SDavid du Colombier numerr.type = numerr.escarg = 0; numerr.esc = k;
5733e12c5d1SDavid du Colombier if (i = hmot())
5743e12c5d1SDavid du Colombier return(i);
5753e12c5d1SDavid du Colombier goto g0;
5763e12c5d1SDavid du Colombier case '|': /* narrow space */
5773e12c5d1SDavid du Colombier if (NROFF)
5783e12c5d1SDavid du Colombier goto g0;
5793e12c5d1SDavid du Colombier return(makem((int)(EM)/6));
5803e12c5d1SDavid du Colombier case '^': /* half narrow space */
5813e12c5d1SDavid du Colombier if (NROFF)
5823e12c5d1SDavid du Colombier goto g0;
5833e12c5d1SDavid du Colombier return(makem((int)(EM)/12));
5843e12c5d1SDavid du Colombier case 'w': /* width function */
5853e12c5d1SDavid du Colombier setwd();
5863e12c5d1SDavid du Colombier goto g0;
5873e12c5d1SDavid du Colombier case 'p': /* spread */
5883e12c5d1SDavid du Colombier spread++;
5893e12c5d1SDavid du Colombier goto g0;
5903e12c5d1SDavid du Colombier case 'N': /* absolute character number */
591219b2ee8SDavid du Colombier numerr.type = numerr.escarg = 0; numerr.esc = k;
5923e12c5d1SDavid du Colombier if ((i = setabs()) == 0)
5933e12c5d1SDavid du Colombier goto g0;
5943e12c5d1SDavid du Colombier return i;
5953e12c5d1SDavid du Colombier case 'H': /* character height */
596219b2ee8SDavid du Colombier numerr.type = numerr.escarg = 0; numerr.esc = k;
5973e12c5d1SDavid du Colombier return(setht());
5983e12c5d1SDavid du Colombier case 'S': /* slant */
599219b2ee8SDavid du Colombier numerr.type = numerr.escarg = 0; numerr.esc = k;
6003e12c5d1SDavid du Colombier return(setslant());
6013e12c5d1SDavid du Colombier case 'z': /* zero with char */
6023e12c5d1SDavid du Colombier return(setz());
6033e12c5d1SDavid du Colombier case 'l': /* hor line */
604219b2ee8SDavid du Colombier numerr.type = numerr.escarg = 0; numerr.esc = k;
6053e12c5d1SDavid du Colombier setline();
6063e12c5d1SDavid du Colombier goto g0;
6073e12c5d1SDavid du Colombier case 'L': /* vert line */
608219b2ee8SDavid du Colombier numerr.type = numerr.escarg = 0; numerr.esc = k;
6093e12c5d1SDavid du Colombier setvline();
6103e12c5d1SDavid du Colombier goto g0;
6113e12c5d1SDavid du Colombier case 'D': /* drawing function */
612219b2ee8SDavid du Colombier numerr.type = numerr.escarg = 0; numerr.esc = k;
6133e12c5d1SDavid du Colombier setdraw();
6143e12c5d1SDavid du Colombier goto g0;
6153e12c5d1SDavid du Colombier case 'X': /* \X'...' for copy through */
6163e12c5d1SDavid du Colombier setxon();
6173e12c5d1SDavid du Colombier goto g0;
6183e12c5d1SDavid du Colombier case 'b': /* bracket */
6193e12c5d1SDavid du Colombier setbra();
6203e12c5d1SDavid du Colombier goto g0;
6213e12c5d1SDavid du Colombier case 'o': /* overstrike */
6223e12c5d1SDavid du Colombier setov();
6233e12c5d1SDavid du Colombier goto g0;
6243e12c5d1SDavid du Colombier case 'k': /* mark hor place */
6253e12c5d1SDavid du Colombier if ((k = findr(getsn())) != -1) {
626219b2ee8SDavid du Colombier numtabp[k].val = numtabp[HP].val;
6273e12c5d1SDavid du Colombier }
6283e12c5d1SDavid du Colombier goto g0;
6293e12c5d1SDavid du Colombier case '0': /* number space */
6303e12c5d1SDavid du Colombier return(makem(width('0' | chbits)));
6313e12c5d1SDavid du Colombier case 'x': /* extra line space */
632219b2ee8SDavid du Colombier numerr.type = numerr.escarg = 0; numerr.esc = k;
6333e12c5d1SDavid du Colombier if (i = xlss())
6343e12c5d1SDavid du Colombier return(i);
6353e12c5d1SDavid du Colombier goto g0;
6363e12c5d1SDavid du Colombier case 'u': /* half em up */
6373e12c5d1SDavid du Colombier case 'r': /* full em up */
6383e12c5d1SDavid du Colombier case 'd': /* half em down */
6393e12c5d1SDavid du Colombier return(sethl(k));
6403e12c5d1SDavid du Colombier default:
6413e12c5d1SDavid du Colombier return(j);
6423e12c5d1SDavid du Colombier }
6433e12c5d1SDavid du Colombier /* NOTREACHED */
6443e12c5d1SDavid du Colombier }
6453e12c5d1SDavid du Colombier
setxon(void)6463e12c5d1SDavid du Colombier void setxon(void) /* \X'...' for copy through */
6473e12c5d1SDavid du Colombier {
6483e12c5d1SDavid du Colombier Tchar xbuf[NC];
6493e12c5d1SDavid du Colombier Tchar *i;
6503e12c5d1SDavid du Colombier Tchar c;
6513e12c5d1SDavid du Colombier int delim, k;
6523e12c5d1SDavid du Colombier
6533e12c5d1SDavid du Colombier if (ismot(c = getch()))
6543e12c5d1SDavid du Colombier return;
6553e12c5d1SDavid du Colombier delim = cbits(c);
6563e12c5d1SDavid du Colombier i = xbuf;
6573e12c5d1SDavid du Colombier *i++ = XON | chbits;
6583e12c5d1SDavid du Colombier while ((k = cbits(c = getch())) != delim && k != '\n' && i < xbuf+NC-1) {
6593e12c5d1SDavid du Colombier if (k == ' ')
6603e12c5d1SDavid du Colombier setcbits(c, WORDSP);
6613e12c5d1SDavid du Colombier *i++ = c | ZBIT;
6623e12c5d1SDavid du Colombier }
6633e12c5d1SDavid du Colombier *i++ = XOFF | chbits;
6643e12c5d1SDavid du Colombier *i = 0;
6653e12c5d1SDavid du Colombier pushback(xbuf);
6663e12c5d1SDavid du Colombier }
6673e12c5d1SDavid du Colombier
6683e12c5d1SDavid du Colombier
6693e12c5d1SDavid du Colombier char ifilt[32] = { 0, 001, 002, 003, 0, 005, 006, 007, 010, 011, 012 };
6703e12c5d1SDavid du Colombier
getch0(void)6713e12c5d1SDavid du Colombier Tchar getch0(void)
6723e12c5d1SDavid du Colombier {
6733e12c5d1SDavid du Colombier Tchar i;
6743e12c5d1SDavid du Colombier
6753e12c5d1SDavid du Colombier again:
6763e12c5d1SDavid du Colombier if (pbp > lastpbp)
6773e12c5d1SDavid du Colombier i = *--pbp;
6783e12c5d1SDavid du Colombier else if (ip) {
6793e12c5d1SDavid du Colombier /* i = rbf(); */
6803e12c5d1SDavid du Colombier i = rbf0(ip);
6813e12c5d1SDavid du Colombier if (i == 0)
6823e12c5d1SDavid du Colombier i = rbf();
6833e12c5d1SDavid du Colombier else {
6843e12c5d1SDavid du Colombier ++ip;
6853e12c5d1SDavid du Colombier if (pastend(ip)) {
6863e12c5d1SDavid du Colombier --ip;
6873e12c5d1SDavid du Colombier rbf();
6883e12c5d1SDavid du Colombier }
6893e12c5d1SDavid du Colombier }
6903e12c5d1SDavid du Colombier } else {
6913e12c5d1SDavid du Colombier if (donef || ndone)
6923e12c5d1SDavid du Colombier done(0);
6933e12c5d1SDavid du Colombier if (nx || 1) { /* BUG: was ibufp >= eibuf, so EOF test is wrong */
694219b2ee8SDavid du Colombier if (nfo < 0)
695219b2ee8SDavid du Colombier ERROR "in getch0, nfo = %d", nfo WARN;
6963e12c5d1SDavid du Colombier if (nfo == 0) {
6973e12c5d1SDavid du Colombier g0:
6983e12c5d1SDavid du Colombier if (nextfile()) {
6993e12c5d1SDavid du Colombier if (ip)
7003e12c5d1SDavid du Colombier goto again;
7013e12c5d1SDavid du Colombier }
7023e12c5d1SDavid du Colombier }
7033e12c5d1SDavid du Colombier nx = 0;
704219b2ee8SDavid du Colombier #ifdef UNICODE
705219b2ee8SDavid du Colombier if (MB_CUR_MAX > 1)
706219b2ee8SDavid du Colombier i = get1ch(ifile);
707219b2ee8SDavid du Colombier else
708219b2ee8SDavid du Colombier #endif /*UNICODE*/
709219b2ee8SDavid du Colombier i = getc(ifile);
710219b2ee8SDavid du Colombier if (i == EOF)
7113e12c5d1SDavid du Colombier goto g0;
7123e12c5d1SDavid du Colombier if (ip)
7133e12c5d1SDavid du Colombier goto again;
7143e12c5d1SDavid du Colombier }
715219b2ee8SDavid du Colombier if (i >= 040) /* zapped: && i < 0177 */
7163e12c5d1SDavid du Colombier goto g4;
7173e12c5d1SDavid du Colombier i = ifilt[i];
7183e12c5d1SDavid du Colombier }
7193e12c5d1SDavid du Colombier if (cbits(i) == IMP && !raw)
7203e12c5d1SDavid du Colombier goto again;
721219b2ee8SDavid du Colombier if (i == 0 && !init && !raw) { /* zapped: || i == 0177 */
7223e12c5d1SDavid du Colombier goto again;
7233e12c5d1SDavid du Colombier }
7243e12c5d1SDavid du Colombier g4:
7253e12c5d1SDavid du Colombier if (ismot(i))
7263e12c5d1SDavid du Colombier return i;
7273e12c5d1SDavid du Colombier if (copyf == 0 && sfbits(i) == 0)
7283e12c5d1SDavid du Colombier i |= chbits;
7293e12c5d1SDavid du Colombier if (cbits(i) == eschar && !raw)
7303e12c5d1SDavid du Colombier setcbits(i, ESC);
7313e12c5d1SDavid du Colombier return(i);
7323e12c5d1SDavid du Colombier }
7333e12c5d1SDavid du Colombier
734219b2ee8SDavid du Colombier
735219b2ee8SDavid du Colombier #ifdef UNICODE
get1ch(FILE * fp)7363e12c5d1SDavid du Colombier Tchar get1ch(FILE *fp) /* get one "character" from input, figure out what alphabet */
7373e12c5d1SDavid du Colombier {
7383e12c5d1SDavid du Colombier wchar_t wc;
7393e12c5d1SDavid du Colombier char buf[100], *p;
7403e12c5d1SDavid du Colombier int i, n, c;
7413e12c5d1SDavid du Colombier
742*14f51593SDavid du Colombier n = c = 0;
7433e12c5d1SDavid du Colombier for (i = 0, p = buf; i < MB_CUR_MAX; i++) {
7443e12c5d1SDavid du Colombier if ((c = getc(fp)) == EOF)
7453e12c5d1SDavid du Colombier return c;
7463e12c5d1SDavid du Colombier *p++ = c;
7473e12c5d1SDavid du Colombier if ((n = mbtowc(&wc, buf, p-buf)) >= 0)
7483e12c5d1SDavid du Colombier break;
7493e12c5d1SDavid du Colombier }
7503e12c5d1SDavid du Colombier if (n == 1) /* real ascii, presumably */
7513e12c5d1SDavid du Colombier return wc;
7523e12c5d1SDavid du Colombier if (n == 0)
7533e12c5d1SDavid du Colombier return p[-1]; /* illegal, but what else to do? */
7543e12c5d1SDavid du Colombier if (c == EOF)
7553e12c5d1SDavid du Colombier return EOF;
7563e12c5d1SDavid du Colombier *p = 0;
7573e12c5d1SDavid du Colombier return chadd(buf, MBchar, Install); /* add name even if haven't seen it */
7583e12c5d1SDavid du Colombier }
759219b2ee8SDavid du Colombier #endif /*UNICODE*/
7603e12c5d1SDavid du Colombier
pushback(Tchar * b)7613e12c5d1SDavid du Colombier void pushback(Tchar *b)
7623e12c5d1SDavid du Colombier {
7633e12c5d1SDavid du Colombier Tchar *ob = b;
7643e12c5d1SDavid du Colombier
7653e12c5d1SDavid du Colombier while (*b++)
7663e12c5d1SDavid du Colombier ;
7673e12c5d1SDavid du Colombier b--;
7683e12c5d1SDavid du Colombier while (b > ob && pbp < &pbbuf[NC-3])
7693e12c5d1SDavid du Colombier *pbp++ = *--b;
7703e12c5d1SDavid du Colombier if (pbp >= &pbbuf[NC-3]) {
7713e12c5d1SDavid du Colombier ERROR "pushback overflow" WARN;
7723e12c5d1SDavid du Colombier done(2);
7733e12c5d1SDavid du Colombier }
7743e12c5d1SDavid du Colombier }
7753e12c5d1SDavid du Colombier
cpushback(char * b)7763e12c5d1SDavid du Colombier void cpushback(char *b)
7773e12c5d1SDavid du Colombier {
7783e12c5d1SDavid du Colombier char *ob = b;
7793e12c5d1SDavid du Colombier
7803e12c5d1SDavid du Colombier while (*b++)
7813e12c5d1SDavid du Colombier ;
7823e12c5d1SDavid du Colombier b--;
7833e12c5d1SDavid du Colombier while (b > ob && pbp < &pbbuf[NC-3])
7843e12c5d1SDavid du Colombier *pbp++ = *--b;
7853e12c5d1SDavid du Colombier if (pbp >= &pbbuf[NC-3]) {
7863e12c5d1SDavid du Colombier ERROR "cpushback overflow" WARN;
7873e12c5d1SDavid du Colombier done(2);
7883e12c5d1SDavid du Colombier }
7893e12c5d1SDavid du Colombier }
7903e12c5d1SDavid du Colombier
nextfile(void)7913e12c5d1SDavid du Colombier int nextfile(void)
7923e12c5d1SDavid du Colombier {
7933e12c5d1SDavid du Colombier char *p;
7943e12c5d1SDavid du Colombier
7953e12c5d1SDavid du Colombier n0:
7963e12c5d1SDavid du Colombier if (ifile != stdin)
7973e12c5d1SDavid du Colombier fclose(ifile);
798219b2ee8SDavid du Colombier if (ifi > 0 && !nx) {
7993e12c5d1SDavid du Colombier if (popf())
8003e12c5d1SDavid du Colombier goto n0; /* popf error */
8013e12c5d1SDavid du Colombier return(1); /* popf ok */
8023e12c5d1SDavid du Colombier }
8033e12c5d1SDavid du Colombier if (nx || nmfi < mflg) {
8043e12c5d1SDavid du Colombier p = mfiles[nmfi++];
8053e12c5d1SDavid du Colombier if (*p != 0)
8063e12c5d1SDavid du Colombier goto n1;
8073e12c5d1SDavid du Colombier }
8083e12c5d1SDavid du Colombier if (rargc-- <= 0) {
809219b2ee8SDavid du Colombier if ((nfo -= mflg) && !stdi) {
8103e12c5d1SDavid du Colombier done(0);
811219b2ee8SDavid du Colombier }
8123e12c5d1SDavid du Colombier nfo++;
813219b2ee8SDavid du Colombier numtabp[CD].val = stdi = mflg = 0;
8143e12c5d1SDavid du Colombier ifile = stdin;
8153e12c5d1SDavid du Colombier strcpy(cfname[ifi], "stdin");
8163e12c5d1SDavid du Colombier return(0);
8173e12c5d1SDavid du Colombier }
8183e12c5d1SDavid du Colombier p = (argp++)[0];
819219b2ee8SDavid du Colombier if (rargc >= 0)
820219b2ee8SDavid du Colombier cfname[ifi][0] = 0;
8213e12c5d1SDavid du Colombier n1:
822219b2ee8SDavid du Colombier numtabp[CD].val = 0;
8233e12c5d1SDavid du Colombier if (p[0] == '-' && p[1] == 0) {
8243e12c5d1SDavid du Colombier ifile = stdin;
8253e12c5d1SDavid du Colombier strcpy(cfname[ifi], "stdin");
8263e12c5d1SDavid du Colombier } else if ((ifile = fopen(p, "r")) == NULL) {
8273e12c5d1SDavid du Colombier ERROR "cannot open file %s", p WARN;
8283e12c5d1SDavid du Colombier nfo -= mflg;
8293e12c5d1SDavid du Colombier done(02);
8303e12c5d1SDavid du Colombier } else
8313e12c5d1SDavid du Colombier strcpy(cfname[ifi],p);
8323e12c5d1SDavid du Colombier nfo++;
8333e12c5d1SDavid du Colombier return(0);
8343e12c5d1SDavid du Colombier }
8353e12c5d1SDavid du Colombier
8363e12c5d1SDavid du Colombier
popf(void)8373e12c5d1SDavid du Colombier popf(void)
8383e12c5d1SDavid du Colombier {
8393e12c5d1SDavid du Colombier --ifi;
8403e12c5d1SDavid du Colombier if (ifi < 0) {
8413e12c5d1SDavid du Colombier ERROR "popf went negative" WARN;
8423e12c5d1SDavid du Colombier return 1;
8433e12c5d1SDavid du Colombier }
844219b2ee8SDavid du Colombier numtabp[CD].val = cfline[ifi]; /* restore line counter */
8453e12c5d1SDavid du Colombier ip = ipl[ifi]; /* input pointer */
8463e12c5d1SDavid du Colombier ifile = ifl[ifi]; /* input FILE * */
8473e12c5d1SDavid du Colombier return(0);
8483e12c5d1SDavid du Colombier }
8493e12c5d1SDavid du Colombier
8503e12c5d1SDavid du Colombier
flushi(void)8513e12c5d1SDavid du Colombier void flushi(void)
8523e12c5d1SDavid du Colombier {
8533e12c5d1SDavid du Colombier if (nflush)
8543e12c5d1SDavid du Colombier return;
8553e12c5d1SDavid du Colombier ch = 0;
8563e12c5d1SDavid du Colombier copyf++;
8573e12c5d1SDavid du Colombier while (!nlflg) {
8583e12c5d1SDavid du Colombier if (donef && frame == stk)
8593e12c5d1SDavid du Colombier break;
8603e12c5d1SDavid du Colombier getch();
8613e12c5d1SDavid du Colombier }
8623e12c5d1SDavid du Colombier copyf--;
8633e12c5d1SDavid du Colombier }
8643e12c5d1SDavid du Colombier
865219b2ee8SDavid du Colombier /*
866219b2ee8SDavid du Colombier * return 16-bit, ascii/alphabetic character, ignore chars with more bits,
867219b2ee8SDavid du Colombier * (internal names), spaces and special cookies (below 040).
868219b2ee8SDavid du Colombier * Leave STX ETX ENQ ACK and BELL in to maintain compatibility with v7 troff.
869219b2ee8SDavid du Colombier */
getach(void)870219b2ee8SDavid du Colombier getach(void)
8713e12c5d1SDavid du Colombier {
8723e12c5d1SDavid du Colombier Tchar i;
8733e12c5d1SDavid du Colombier int j;
8743e12c5d1SDavid du Colombier
8753e12c5d1SDavid du Colombier lgf++;
8763e12c5d1SDavid du Colombier j = cbits(i = getch());
877219b2ee8SDavid du Colombier if (ismot(i)
878219b2ee8SDavid du Colombier || j > SHORTMASK
879219b2ee8SDavid du Colombier || (j <= 040 && j != 002 /*STX*/
880219b2ee8SDavid du Colombier && j != 003 /*ETX*/
881219b2ee8SDavid du Colombier && j != 005 /*ENQ*/
882219b2ee8SDavid du Colombier && j != 006 /*ACK*/
883219b2ee8SDavid du Colombier && j != 007)) { /*BELL*/
8843e12c5d1SDavid du Colombier ch = i;
8853e12c5d1SDavid du Colombier j = 0;
8863e12c5d1SDavid du Colombier }
8873e12c5d1SDavid du Colombier lgf--;
8883e12c5d1SDavid du Colombier return j;
8893e12c5d1SDavid du Colombier }
8903e12c5d1SDavid du Colombier
8913e12c5d1SDavid du Colombier
casenx(void)8923e12c5d1SDavid du Colombier void casenx(void)
8933e12c5d1SDavid du Colombier {
8943e12c5d1SDavid du Colombier lgf++;
8953e12c5d1SDavid du Colombier skip();
8963e12c5d1SDavid du Colombier getname();
8973e12c5d1SDavid du Colombier nx++;
8983e12c5d1SDavid du Colombier if (nmfi > 0)
8993e12c5d1SDavid du Colombier nmfi--;
9003e12c5d1SDavid du Colombier strcpy(mfiles[nmfi], nextf);
9013e12c5d1SDavid du Colombier nextfile();
9023e12c5d1SDavid du Colombier nlflg++;
9033e12c5d1SDavid du Colombier ip = 0;
9043e12c5d1SDavid du Colombier pendt = 0;
9053e12c5d1SDavid du Colombier frame = stk;
9063e12c5d1SDavid du Colombier nxf = frame + 1;
9073e12c5d1SDavid du Colombier }
9083e12c5d1SDavid du Colombier
9093e12c5d1SDavid du Colombier
getname(void)9103e12c5d1SDavid du Colombier getname(void)
9113e12c5d1SDavid du Colombier {
9123e12c5d1SDavid du Colombier int j, k;
9133e12c5d1SDavid du Colombier
9143e12c5d1SDavid du Colombier lgf++;
9153e12c5d1SDavid du Colombier for (k = 0; k < NS - 1; k++) {
916219b2ee8SDavid du Colombier j = getach();
917219b2ee8SDavid du Colombier if (!j)
9183e12c5d1SDavid du Colombier break;
9193e12c5d1SDavid du Colombier nextf[k] = j;
9203e12c5d1SDavid du Colombier }
9213e12c5d1SDavid du Colombier nextf[k] = 0;
9223e12c5d1SDavid du Colombier lgf--;
9233e12c5d1SDavid du Colombier return(nextf[0]);
9243e12c5d1SDavid du Colombier }
9253e12c5d1SDavid du Colombier
9263e12c5d1SDavid du Colombier
caseso(void)9273e12c5d1SDavid du Colombier void caseso(void)
9283e12c5d1SDavid du Colombier {
9293e12c5d1SDavid du Colombier FILE *fp;
9303e12c5d1SDavid du Colombier
9313e12c5d1SDavid du Colombier lgf++;
9323e12c5d1SDavid du Colombier nextf[0] = 0;
933*14f51593SDavid du Colombier fp = NULL;
9343e12c5d1SDavid du Colombier if (skip() || !getname() || (fp = fopen(nextf, "r")) == NULL || ifi >= NSO) {
9353e12c5d1SDavid du Colombier ERROR "can't open file %s", nextf WARN;
9363e12c5d1SDavid du Colombier done(02);
9373e12c5d1SDavid du Colombier }
9383e12c5d1SDavid du Colombier strcpy(cfname[ifi+1], nextf);
939219b2ee8SDavid du Colombier cfline[ifi] = numtabp[CD].val; /*hold line counter*/
940219b2ee8SDavid du Colombier numtabp[CD].val = 0;
9413e12c5d1SDavid du Colombier flushi();
9423e12c5d1SDavid du Colombier ifl[ifi] = ifile;
9433e12c5d1SDavid du Colombier ifile = fp;
9443e12c5d1SDavid du Colombier ipl[ifi] = ip;
9453e12c5d1SDavid du Colombier ip = 0;
9463e12c5d1SDavid du Colombier nx++;
9473e12c5d1SDavid du Colombier nflush++;
9483e12c5d1SDavid du Colombier ifi++;
9493e12c5d1SDavid du Colombier }
9503e12c5d1SDavid du Colombier
caself(void)9513e12c5d1SDavid du Colombier void caself(void) /* set line number and file */
9523e12c5d1SDavid du Colombier {
9533e12c5d1SDavid du Colombier int n;
9543e12c5d1SDavid du Colombier
9553e12c5d1SDavid du Colombier if (skip())
9563e12c5d1SDavid du Colombier return;
9573e12c5d1SDavid du Colombier n = atoi0();
958219b2ee8SDavid du Colombier if (!nonumb)
959219b2ee8SDavid du Colombier cfline[ifi] = numtabp[CD].val = n - 1;
960219b2ee8SDavid du Colombier if (!skip())
961219b2ee8SDavid du Colombier if (getname()) { /* eats '\n' ? */
9623e12c5d1SDavid du Colombier strcpy(cfname[ifi], nextf);
963219b2ee8SDavid du Colombier if (!nonumb)
964219b2ee8SDavid du Colombier numtabp[CD].val--;
965219b2ee8SDavid du Colombier }
9663e12c5d1SDavid du Colombier }
9673e12c5d1SDavid du Colombier
cpout(FILE * fin,char * token)968219b2ee8SDavid du Colombier void cpout(FILE *fin, char *token)
969219b2ee8SDavid du Colombier {
970219b2ee8SDavid du Colombier int n;
971219b2ee8SDavid du Colombier char buf[1024];
972219b2ee8SDavid du Colombier
973219b2ee8SDavid du Colombier if (token) { /* BUG: There should be no NULL bytes in input */
974219b2ee8SDavid du Colombier char *newl = buf;
975219b2ee8SDavid du Colombier while ((fgets(buf, sizeof buf, fin)) != NULL) {
976219b2ee8SDavid du Colombier if (newl) {
977219b2ee8SDavid du Colombier numtabp[CD].val++; /* line number */
978219b2ee8SDavid du Colombier if (strcmp(token, buf) == 0)
979219b2ee8SDavid du Colombier return;
980219b2ee8SDavid du Colombier }
981219b2ee8SDavid du Colombier newl = strchr(buf, '\n');
982219b2ee8SDavid du Colombier fputs(buf, ptid);
983219b2ee8SDavid du Colombier }
984219b2ee8SDavid du Colombier } else {
985219b2ee8SDavid du Colombier while ((n = fread(buf, sizeof *buf, sizeof buf, fin)) > 0)
986219b2ee8SDavid du Colombier fwrite(buf, n, 1, ptid);
987219b2ee8SDavid du Colombier fclose(fin);
988219b2ee8SDavid du Colombier }
989219b2ee8SDavid du Colombier }
9903e12c5d1SDavid du Colombier
casecf(void)9913e12c5d1SDavid du Colombier void casecf(void)
9923e12c5d1SDavid du Colombier { /* copy file without change */
993219b2ee8SDavid du Colombier FILE *fd;
994219b2ee8SDavid du Colombier char *eof, *p;
9953e12c5d1SDavid du Colombier extern int hpos, esc, po;
9963e12c5d1SDavid du Colombier
9973e12c5d1SDavid du Colombier /* this may not make much sense in nroff... */
9983e12c5d1SDavid du Colombier
9993e12c5d1SDavid du Colombier lgf++;
10003e12c5d1SDavid du Colombier nextf[0] = 0;
1001219b2ee8SDavid du Colombier if (!skip() && getname()) {
1002219b2ee8SDavid du Colombier if (strncmp("<<", nextf, 2) != 0) {
1003219b2ee8SDavid du Colombier if ((fd = fopen(nextf, "r")) == NULL) {
10043e12c5d1SDavid du Colombier ERROR "can't open file %s", nextf WARN;
10053e12c5d1SDavid du Colombier done(02);
10063e12c5d1SDavid du Colombier }
1007219b2ee8SDavid du Colombier eof = (char *) NULL;
1008219b2ee8SDavid du Colombier } else { /* current file */
1009219b2ee8SDavid du Colombier if (pbp > lastpbp || ip) {
1010219b2ee8SDavid du Colombier ERROR "casecf: not reading from file" WARN;
1011219b2ee8SDavid du Colombier done(02);
1012219b2ee8SDavid du Colombier }
1013219b2ee8SDavid du Colombier eof = &nextf[2];
1014219b2ee8SDavid du Colombier if (!*eof) {
1015219b2ee8SDavid du Colombier ERROR "casecf: missing end of input token" WARN;
1016219b2ee8SDavid du Colombier done(02);
1017219b2ee8SDavid du Colombier }
1018219b2ee8SDavid du Colombier p = eof;
1019219b2ee8SDavid du Colombier while(*++p)
1020219b2ee8SDavid du Colombier ;
1021219b2ee8SDavid du Colombier *p++ = '\n';
1022219b2ee8SDavid du Colombier *p = 0;
1023219b2ee8SDavid du Colombier fd = ifile;
1024219b2ee8SDavid du Colombier }
1025219b2ee8SDavid du Colombier } else {
1026219b2ee8SDavid du Colombier ERROR "casecf: no argument" WARN;
1027219b2ee8SDavid du Colombier lgf--;
1028219b2ee8SDavid du Colombier return;
1029219b2ee8SDavid du Colombier }
10303e12c5d1SDavid du Colombier lgf--;
10313e12c5d1SDavid du Colombier
10323e12c5d1SDavid du Colombier /* make it into a clean state, be sure that everything is out */
10333e12c5d1SDavid du Colombier tbreak();
10343e12c5d1SDavid du Colombier hpos = po;
10353e12c5d1SDavid du Colombier esc = 0;
10363e12c5d1SDavid du Colombier ptesc(); /* to left margin */
10373e12c5d1SDavid du Colombier esc = un;
10383e12c5d1SDavid du Colombier ptesc();
10393e12c5d1SDavid du Colombier ptlead();
10403e12c5d1SDavid du Colombier ptps();
10413e12c5d1SDavid du Colombier ptfont();
10423e12c5d1SDavid du Colombier flusho();
1043219b2ee8SDavid du Colombier cpout(fd, eof);
10443e12c5d1SDavid du Colombier ptps();
10453e12c5d1SDavid du Colombier ptfont();
10463e12c5d1SDavid du Colombier }
10473e12c5d1SDavid du Colombier
getline(char * s,int n)10483e12c5d1SDavid du Colombier void getline(char *s, int n) /* get rest of input line into s */
10493e12c5d1SDavid du Colombier {
10503e12c5d1SDavid du Colombier int i;
10513e12c5d1SDavid du Colombier
10523e12c5d1SDavid du Colombier lgf++;
10533e12c5d1SDavid du Colombier copyf++;
10543e12c5d1SDavid du Colombier skip();
10553e12c5d1SDavid du Colombier for (i = 0; i < n-1; i++)
10563e12c5d1SDavid du Colombier if ((s[i] = cbits(getch())) == '\n' || s[i] == RIGHT)
10573e12c5d1SDavid du Colombier break;
10583e12c5d1SDavid du Colombier s[i] = 0;
10593e12c5d1SDavid du Colombier copyf--;
10603e12c5d1SDavid du Colombier lgf--;
10613e12c5d1SDavid du Colombier }
10623e12c5d1SDavid du Colombier
casesy(void)10633e12c5d1SDavid du Colombier void casesy(void) /* call system */
10643e12c5d1SDavid du Colombier {
10653e12c5d1SDavid du Colombier char sybuf[NTM];
10663e12c5d1SDavid du Colombier
10673e12c5d1SDavid du Colombier getline(sybuf, NTM);
10683e12c5d1SDavid du Colombier system(sybuf);
10693e12c5d1SDavid du Colombier }
10703e12c5d1SDavid du Colombier
10713e12c5d1SDavid du Colombier
getpn(char * a)10723e12c5d1SDavid du Colombier void getpn(char *a)
10733e12c5d1SDavid du Colombier {
10743e12c5d1SDavid du Colombier int n, neg;
10753e12c5d1SDavid du Colombier
10763e12c5d1SDavid du Colombier if (*a == 0)
10773e12c5d1SDavid du Colombier return;
10783e12c5d1SDavid du Colombier neg = 0;
10793e12c5d1SDavid du Colombier for ( ; *a; a++)
10803e12c5d1SDavid du Colombier switch (*a) {
10813e12c5d1SDavid du Colombier case '+':
10823e12c5d1SDavid du Colombier case ',':
10833e12c5d1SDavid du Colombier continue;
10843e12c5d1SDavid du Colombier case '-':
10853e12c5d1SDavid du Colombier neg = 1;
10863e12c5d1SDavid du Colombier continue;
10873e12c5d1SDavid du Colombier default:
10883e12c5d1SDavid du Colombier n = 0;
10893e12c5d1SDavid du Colombier if (isdigit(*a)) {
10903e12c5d1SDavid du Colombier do
10913e12c5d1SDavid du Colombier n = 10 * n + *a++ - '0';
10923e12c5d1SDavid du Colombier while (isdigit(*a));
10933e12c5d1SDavid du Colombier a--;
10943e12c5d1SDavid du Colombier } else
10953e12c5d1SDavid du Colombier n = 9999;
10963e12c5d1SDavid du Colombier *pnp++ = neg ? -n : n;
10973e12c5d1SDavid du Colombier neg = 0;
10983e12c5d1SDavid du Colombier if (pnp >= &pnlist[NPN-2]) {
10993e12c5d1SDavid du Colombier ERROR "too many page numbers" WARN;
11003e12c5d1SDavid du Colombier done3(-3);
11013e12c5d1SDavid du Colombier }
11023e12c5d1SDavid du Colombier }
11033e12c5d1SDavid du Colombier if (neg)
11043e12c5d1SDavid du Colombier *pnp++ = -9999;
1105219b2ee8SDavid du Colombier *pnp = -INT_MAX;
11063e12c5d1SDavid du Colombier print = 0;
11073e12c5d1SDavid du Colombier pnp = pnlist;
1108219b2ee8SDavid du Colombier if (*pnp != -INT_MAX)
11093e12c5d1SDavid du Colombier chkpn();
11103e12c5d1SDavid du Colombier }
11113e12c5d1SDavid du Colombier
11123e12c5d1SDavid du Colombier
setrpt(void)11133e12c5d1SDavid du Colombier void setrpt(void)
11143e12c5d1SDavid du Colombier {
11153e12c5d1SDavid du Colombier Tchar i, j;
11163e12c5d1SDavid du Colombier
11173e12c5d1SDavid du Colombier copyf++;
11183e12c5d1SDavid du Colombier raw++;
11193e12c5d1SDavid du Colombier i = getch0();
11203e12c5d1SDavid du Colombier copyf--;
11213e12c5d1SDavid du Colombier raw--;
11223e12c5d1SDavid du Colombier if ((long) i < 0 || cbits(j = getch0()) == RPT)
11233e12c5d1SDavid du Colombier return;
11243e12c5d1SDavid du Colombier while (i > 0 && pbp < &pbbuf[NC-3]) {
11253e12c5d1SDavid du Colombier i--;
11263e12c5d1SDavid du Colombier *pbp++ = j;
11273e12c5d1SDavid du Colombier }
11283e12c5d1SDavid du Colombier }
1129