12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130 |
- /*
- * n1.c
- *
- * consume options, initialization, main loop,
- * input routines, escape function calling
- */
- #include "tdef.h"
- #include "fns.h"
- #include "ext.h"
- #include "dwbinit.h"
- #include <setjmp.h>
- #include <time.h>
- char *Version = "March 11, 1994";
- #ifndef DWBVERSION
- #define DWBVERSION "???"
- #endif
- char *DWBfontdir = FONTDIR;
- char *DWBntermdir = NTERMDIR;
- char *DWBalthyphens = ALTHYPHENS;
- char *DWBhomedir = "";
- dwbinit dwbpaths[] = {
- &DWBfontdir, NULL, 0,
- &DWBntermdir, NULL, 0,
- &DWBalthyphens, NULL, 0,
- &DWBhomedir, NULL, 0,
- NULL, nextf, NS,
- NULL, NULL, 0
- };
- int TROFF = 1; /* assume we started in troff... */
- jmp_buf sjbuf;
- Offset ipl[NSO];
- static FILE *ifile = stdin;
- static FILE *ifl[NSO]; /* open input file pointers */
- char cfname[NSO+1][NS] = { "stdin" }; /* file name stack */
- int cfline[NSO]; /* input line count stack */
- char *progname; /* program name (troff or nroff) */
- int trace = 0; /* tracing mode: default off */
- int trace1 = 0;
- main(int argc, char *argv[])
- {
- char *p;
- int j;
- Tchar i;
- char buf[100];
- buf[0] = '\0'; /* make sure it's empty (silly 3b2) */
- progname = argv[0];
- if ((p = strrchr(progname, '/')) == NULL)
- p = progname;
- else
- p++;
- DWBinit(progname, dwbpaths);
- if (strcmp(p, "nroff") == 0)
- TROFF = 0;
- #ifdef UNICODE
- alphabet = 128; /* unicode for plan 9 */
- #endif /*UNICODE*/
- mnspace();
- nnspace();
- mrehash();
- nrehash();
- numtabp[NL].val = -1;
- while (--argc > 0 && (++argv)[0][0] == '-')
- switch (argv[0][1]) {
- case 'N': /* ought to be used first... */
- TROFF = 0;
- break;
- case 'd':
- fprintf(stderr, "troff/nroff version %s\n", Version);
- break;
- case 'F': /* switch font tables from default */
- if (argv[0][2] != '\0') {
- strcpy(termtab, &argv[0][2]);
- strcpy(fontdir, &argv[0][2]);
- } else {
- argv++; argc--;
- strcpy(termtab, argv[0]);
- strcpy(fontdir, argv[0]);
- }
- break;
- case 0:
- goto start;
- case 'i':
- stdi++;
- break;
- case 'n':
- npn = atoi(&argv[0][2]);
- break;
- case 'u': /* set emboldening amount */
- bdtab[3] = atoi(&argv[0][2]);
- if (bdtab[3] < 0 || bdtab[3] > 50)
- bdtab[3] = 0;
- break;
- case 's':
- if (!(stop = atoi(&argv[0][2])))
- stop++;
- break;
- case 'r':
- sprintf(buf + strlen(buf), ".nr %c %s\n",
- argv[0][2], &argv[0][3]);
- /* not yet cpushback(buf);*/
- /* dotnr(&argv[0][2], &argv[0][3]); */
- break;
- case 'm':
- if (mflg++ >= NMF) {
- ERROR "Too many macro packages: %s", argv[0] WARN;
- break;
- }
- strcpy(mfiles[nmfi], nextf);
- strcat(mfiles[nmfi++], &argv[0][2]);
- break;
- case 'o':
- getpn(&argv[0][2]);
- break;
- case 'T':
- strcpy(devname, &argv[0][2]);
- dotT++;
- break;
- case 'a':
- ascii = 1;
- break;
- case 'h':
- hflg++;
- break;
- case 'e':
- eqflg++;
- break;
- case 'q':
- quiet++;
- save_tty();
- break;
- case 'V':
- fprintf(stdout, "%croff: DWB %s\n",
- TROFF ? 't' : 'n', DWBVERSION);
- exit(0);
- case 't':
- if (argv[0][2] != '\0')
- trace = trace1 = argv[0][2];
- break; /* for the sake of compatibility */
- default:
- ERROR "unknown option %s", argv[0] WARN;
- done(02);
- }
- start:
- /*
- * cpushback maintains a LIFO, so push pack the -r arguments
- * in reverse order to maintain a FIFO in case someone did -rC1 -rC3
- */
- if (buf[0]) {
- char *p = buf;
- while(*p++)
- ;
- while(p > buf) {
- while(strncmp(p, ".nr", 3) != 0)
- p--;
- cpushback(p);
- *p-- = '\0';
- }
- }
- argp = argv;
- rargc = argc;
- nmfi = 0;
- init2();
- setjmp(sjbuf);
- loop:
- copyf = lgf = nb = nflush = nlflg = 0;
- if (ip && rbf0(ip) == 0 && ejf && frame->pframe <= ejl && dip == d) {
- nflush++;
- trap = 0;
- eject((Stack *)0);
- goto loop;
- }
- i = getch();
- if (pendt)
- goto Lt;
- if ((j = cbits(i)) == XPAR) {
- copyf++;
- tflg++;
- while (cbits(i) != '\n')
- pchar(i = getch());
- tflg = 0;
- copyf--;
- goto loop;
- }
- if (j == cc || j == c2) {
- if (j == c2)
- nb++;
- copyf++;
- while ((j = cbits(i = getch())) == ' ' || j == '\t')
- ;
- ch = i;
- copyf--;
- control(getrq(), 1);
- flushi();
- goto loop;
- }
- Lt:
- ch = i;
- text();
- if (nlflg)
- numtabp[HP].val = 0;
- goto loop;
- }
- void init2(void)
- {
- int i;
- char buf[100];
- for (i = NTRTAB; --i; )
- trtab[i] = i;
- trtab[UNPAD] = ' ';
- iflg = 0;
- obufp = obuf;
- if (TROFF)
- t_ptinit();
- else
- n_ptinit();
- mchbits();
- cvtime();
- numtabp[PID].val = getpid();
- numtabp[HP].val = init = 0;
- numtabp[NL].val = -1;
- nfo = 0;
- copyf = raw = 0;
- sprintf(buf, ".ds .T %s\n", devname);
- cpushback(buf);
- sprintf(buf, ".ds .P %s\n", DWBhomedir);
- cpushback(buf);
- numtabp[CD].val = -1; /* compensation */
- nx = mflg;
- frame = stk = (Stack *)setbrk(STACKSIZE);
- dip = &d[0];
- nxf = frame + 1;
- for (i = 1; i < NEV; i++) /* propagate the environment */
- envcopy(&env[i], &env[0]);
- for (i = 0; i < NEV; i++) {
- if ((env[i]._word._bufp = (Tchar *)calloc(WDSIZE, sizeof(Tchar))) == NULL) {
- ERROR "not enough room for word buffers" WARN;
- done2(1);
- }
- env[i]._word._size = WDSIZE;
- if ((env[i]._line._bufp = (Tchar *)calloc(LNSIZE, sizeof(Tchar))) == NULL) {
- ERROR "not enough room for line buffers" WARN;
- done2(1);
- }
- env[i]._line._size = LNSIZE;
- }
- if ((oline = (Tchar *)calloc(OLNSIZE, sizeof(Tchar))) == NULL) {
- ERROR "not enough room for line buffers" WARN;
- done2(1);
- }
- olinep = oline;
- olnsize = OLNSIZE;
- blockinit();
- }
- void cvtime(void)
- {
- long tt;
- struct tm *ltime;
- time(&tt);
- ltime = localtime(&tt);
- numtabp[YR].val = ltime->tm_year % 100;
- numtabp[YR].fmt = 2;
- numtabp[MO].val = ltime->tm_mon + 1; /* troff uses 1..12 */
- numtabp[DY].val = ltime->tm_mday;
- numtabp[DW].val = ltime->tm_wday + 1; /* troff uses 1..7 */
- }
- char errbuf[200];
- void errprint(void) /* error message printer */
- {
- int savecd = numtabp[CD].val;
- if (!nlflg)
- numtabp[CD].val++;
- fprintf(stderr, "%s: ", progname);
- fputs(errbuf, stderr);
- if (cfname[ifi][0])
- fprintf(stderr, "; %s:%d", cfname[ifi], numtabp[CD].val);
- fputs("\n", stderr);
- if (cfname[ifi][0])
- stackdump();
- numtabp[CD].val = savecd;
- }
- int control(int a, int b)
- {
- int j, k;
- extern Contab *contabp;
- numerr.type = RQERR;
- numerr.req = a;
- if (a == 0 || (j = findmn(a)) == -1)
- return(0);
- if (contabp[j].f == 0) {
- if (trace & TRMAC)
- fprintf(stderr, "invoke macro %s\n", unpair(a));
- if (dip != d)
- for (k = dilev; k; k--)
- if (d[k].curd == a) {
- ERROR "diversion %s invokes itself during diversion",
- unpair(a) WARN;
- edone(0100);
- }
- nxf->nargs = 0;
- if (b)
- collect();
- flushi();
- return pushi(contabp[j].mx, a); /* BUG??? all that matters is 0/!0 */
- }
- if (b) {
- if (trace & TRREQ)
- fprintf(stderr, "invoke request %s\n", unpair(a));
- (*contabp[j].f)();
- }
- return(0);
- }
- void casept(void)
- {
- int i;
- noscale++;
- if (skip())
- i = trace1;
- else {
- i = max(inumb(&trace), 0);
- if (nonumb)
- i = trace1;
- }
- trace1 = trace;
- trace = i;
- noscale = 0;
- }
- int getrq(void)
- {
- int i, j;
- if ((i = getach()) == 0 || (j = getach()) == 0)
- goto rtn;
- i = PAIR(i, j);
- rtn:
- return(i);
- }
- /*
- * table encodes some special characters, to speed up tests
- * in getch, viz FLSS, RPT, f, \b, \n, fc, tabch, ldrch
- */
- char gchtab[NCHARS] = {
- 000,004,000,000,010,000,000,000, /* fc, ldr */
- 001,002,001,000,001,000,000,000, /* \b, tab, nl, RPT */
- 000,000,000,000,000,000,000,000,
- 000,001,000,001,000,000,000,000, /* FLSS, ESC */
- 000,000,000,000,000,000,000,000,
- 000,000,000,000,000,000,000,000,
- 000,000,000,000,000,000,000,000,
- 000,000,000,000,000,000,000,000,
- 000,000,000,000,000,000,000,000,
- 000,000,000,000,000,000,000,000,
- 000,000,000,000,000,000,000,000,
- 000,000,000,000,000,000,000,000,
- 000,000,000,000,000,000,001,000, /* f */
- 000,000,000,000,000,000,000,000,
- 000,000,000,000,000,000,000,000,
- 000,000,000,000,000,000,000,000,
- };
- int realcbits(Tchar c) /* return character bits, or MOTCH if motion */
- {
- if (ismot(c))
- return MOTCH;
- else
- return c & 0xFFFF;
- }
- Tchar getch(void)
- {
- int k;
- Tchar i, j;
- g0:
- if (ch) {
- i = ch;
- if (cbits(i) == '\n')
- nlflg++;
- ch = 0;
- return(i);
- }
- if (nlflg)
- return('\n');
- i = getch0();
- if (ismot(i))
- return(i);
- k = cbits(i);
- if (k >= sizeof(gchtab)/sizeof(gchtab[0]) || gchtab[k] == 0) /* nothing special */
- return(i);
- if (k != ESC) {
- if (k == '\n') {
- nlflg++;
- if (ip == 0)
- numtabp[CD].val++; /* line number */
- return(k);
- }
- if (k == FLSS) {
- copyf++;
- raw++;
- i = getch0();
- if (!fi)
- flss = i;
- copyf--;
- raw--;
- goto g0;
- }
- if (k == RPT) {
- setrpt();
- goto g0;
- }
- if (!copyf) {
- if (k == 'f' && lg && !lgf) {
- i = getlg(i);
- return(i);
- }
- if (k == fc || k == tabch || k == ldrch) {
- if ((i = setfield(k)) == 0)
- goto g0;
- else
- return(i);
- }
- if (k == '\b') {
- i = makem(-width(' ' | chbits));
- return(i);
- }
- }
- return(i);
- }
- k = cbits(j = getch0());
- if (ismot(j))
- return(j);
- switch (k) {
- case 'n': /* number register */
- setn();
- goto g0;
- case '$': /* argument indicator */
- seta();
- goto g0;
- case '*': /* string indicator */
- setstr();
- goto g0;
- case '{': /* LEFT */
- i = LEFT;
- goto gx;
- case '}': /* RIGHT */
- i = RIGHT;
- goto gx;
- case '"': /* comment */
- while (cbits(i = getch0()) != '\n')
- ;
- if (ip == 0)
- numtabp[CD].val++; /* line number */
- nlflg++;
- return(i);
- /* experiment: put it here instead of copy mode */
- case '(': /* special char name \(xx */
- case 'C': /* \C'...' */
- if ((i = setch(k)) == 0)
- goto g0;
- goto gx;
- case ESC: /* double backslash */
- i = eschar;
- goto gx;
- case 'e': /* printable version of current eschar */
- i = PRESC;
- goto gx;
- case '\n': /* concealed newline */
- numtabp[CD].val++;
- goto g0;
- case ' ': /* unpaddable space */
- i = UNPAD;
- goto gx;
- case '\'': /* \(aa */
- i = ACUTE;
- goto gx;
- case '`': /* \(ga */
- i = GRAVE;
- goto gx;
- case '_': /* \(ul */
- i = UNDERLINE;
- goto gx;
- case '-': /* current font minus */
- i = MINUS;
- goto gx;
- case '&': /* filler */
- i = FILLER;
- goto gx;
- case 'c': /* to be continued */
- i = CONT;
- goto gx;
- case '!': /* transparent indicator */
- i = XPAR;
- goto gx;
- case 't': /* tab */
- i = '\t';
- return(i);
- case 'a': /* leader (SOH) */
- /* old: *pbp++ = LEADER; goto g0; */
- i = LEADER;
- return i;
- case '%': /* ohc */
- i = OHC;
- return(i);
- case 'g': /* return format of a number register */
- setaf(); /* should this really be in copy mode??? */
- goto g0;
- case '.': /* . */
- i = '.';
- gx:
- setsfbits(i, sfbits(j));
- return(i);
- }
- if (copyf) {
- *pbp++ = j;
- return(eschar);
- }
- switch (k) {
- case 'f': /* font indicator */
- setfont(0);
- goto g0;
- case 's': /* size indicator */
- setps();
- goto g0;
- case 'v': /* vert mot */
- numerr.type = numerr.escarg = 0; numerr.esc = k;
- if (i = vmot()) {
- return(i);
- }
- goto g0;
- case 'h': /* horiz mot */
- numerr.type = numerr.escarg = 0; numerr.esc = k;
- if (i = hmot())
- return(i);
- goto g0;
- case '|': /* narrow space */
- if (NROFF)
- goto g0;
- return(makem((int)(EM)/6));
- case '^': /* half narrow space */
- if (NROFF)
- goto g0;
- return(makem((int)(EM)/12));
- case 'w': /* width function */
- setwd();
- goto g0;
- case 'p': /* spread */
- spread++;
- goto g0;
- case 'N': /* absolute character number */
- numerr.type = numerr.escarg = 0; numerr.esc = k;
- if ((i = setabs()) == 0)
- goto g0;
- return i;
- case 'H': /* character height */
- numerr.type = numerr.escarg = 0; numerr.esc = k;
- return(setht());
- case 'S': /* slant */
- numerr.type = numerr.escarg = 0; numerr.esc = k;
- return(setslant());
- case 'z': /* zero with char */
- return(setz());
- case 'l': /* hor line */
- numerr.type = numerr.escarg = 0; numerr.esc = k;
- setline();
- goto g0;
- case 'L': /* vert line */
- numerr.type = numerr.escarg = 0; numerr.esc = k;
- setvline();
- goto g0;
- case 'D': /* drawing function */
- numerr.type = numerr.escarg = 0; numerr.esc = k;
- setdraw();
- goto g0;
- case 'X': /* \X'...' for copy through */
- setxon();
- goto g0;
- case 'b': /* bracket */
- setbra();
- goto g0;
- case 'o': /* overstrike */
- setov();
- goto g0;
- case 'k': /* mark hor place */
- if ((k = findr(getsn())) != -1) {
- numtabp[k].val = numtabp[HP].val;
- }
- goto g0;
- case '0': /* number space */
- return(makem(width('0' | chbits)));
- case 'x': /* extra line space */
- numerr.type = numerr.escarg = 0; numerr.esc = k;
- if (i = xlss())
- return(i);
- goto g0;
- case 'u': /* half em up */
- case 'r': /* full em up */
- case 'd': /* half em down */
- return(sethl(k));
- default:
- return(j);
- }
- /* NOTREACHED */
- }
- void setxon(void) /* \X'...' for copy through */
- {
- Tchar xbuf[NC];
- Tchar *i;
- Tchar c;
- int delim, k;
- if (ismot(c = getch()))
- return;
- delim = cbits(c);
- i = xbuf;
- *i++ = XON | chbits;
- while ((k = cbits(c = getch())) != delim && k != '\n' && i < xbuf+NC-1) {
- if (k == ' ')
- setcbits(c, WORDSP);
- *i++ = c | ZBIT;
- }
- *i++ = XOFF | chbits;
- *i = 0;
- pushback(xbuf);
- }
- char ifilt[32] = { 0, 001, 002, 003, 0, 005, 006, 007, 010, 011, 012 };
- Tchar getch0(void)
- {
- int j;
- Tchar i;
- again:
- if (pbp > lastpbp)
- i = *--pbp;
- else if (ip) {
- /* i = rbf(); */
- i = rbf0(ip);
- if (i == 0)
- i = rbf();
- else {
- ++ip;
- if (pastend(ip)) {
- --ip;
- rbf();
- }
- }
- } else {
- if (donef || ndone)
- done(0);
- if (nx || 1) { /* BUG: was ibufp >= eibuf, so EOF test is wrong */
- if (nfo < 0)
- ERROR "in getch0, nfo = %d", nfo WARN;
- if (nfo == 0) {
- g0:
- if (nextfile()) {
- if (ip)
- goto again;
- }
- }
- nx = 0;
- #ifdef UNICODE
- if (MB_CUR_MAX > 1)
- i = get1ch(ifile);
- else
- #endif /*UNICODE*/
- i = getc(ifile);
- if (i == EOF)
- goto g0;
- if (ip)
- goto again;
- }
- g2:
- if (i >= 040) /* zapped: && i < 0177 */
- goto g4;
- i = ifilt[i];
- }
- if (cbits(i) == IMP && !raw)
- goto again;
- if (i == 0 && !init && !raw) { /* zapped: || i == 0177 */
- goto again;
- }
- g4:
- if (ismot(i))
- return i;
- if (copyf == 0 && sfbits(i) == 0)
- i |= chbits;
- if (cbits(i) == eschar && !raw)
- setcbits(i, ESC);
- return(i);
- }
- #ifdef UNICODE
- Tchar get1ch(FILE *fp) /* get one "character" from input, figure out what alphabet */
- {
- wchar_t wc;
- char buf[100], *p;
- int i, n, c;
- for (i = 0, p = buf; i < MB_CUR_MAX; i++) {
- if ((c = getc(fp)) == EOF)
- return c;
- *p++ = c;
- if ((n = mbtowc(&wc, buf, p-buf)) >= 0)
- break;
- }
- if (n == 1) /* real ascii, presumably */
- return wc;
- if (n == 0)
- return p[-1]; /* illegal, but what else to do? */
- if (c == EOF)
- return EOF;
- *p = 0;
- return chadd(buf, MBchar, Install); /* add name even if haven't seen it */
- }
- #endif /*UNICODE*/
- void pushback(Tchar *b)
- {
- Tchar *ob = b;
- while (*b++)
- ;
- b--;
- while (b > ob && pbp < &pbbuf[NC-3])
- *pbp++ = *--b;
- if (pbp >= &pbbuf[NC-3]) {
- ERROR "pushback overflow" WARN;
- done(2);
- }
- }
- void cpushback(char *b)
- {
- char *ob = b;
- while (*b++)
- ;
- b--;
- while (b > ob && pbp < &pbbuf[NC-3])
- *pbp++ = *--b;
- if (pbp >= &pbbuf[NC-3]) {
- ERROR "cpushback overflow" WARN;
- done(2);
- }
- }
- int nextfile(void)
- {
- char *p;
- n0:
- if (ifile != stdin)
- fclose(ifile);
- if (ifi > 0 && !nx) {
- if (popf())
- goto n0; /* popf error */
- return(1); /* popf ok */
- }
- if (nx || nmfi < mflg) {
- p = mfiles[nmfi++];
- if (*p != 0)
- goto n1;
- }
- if (rargc-- <= 0) {
- if ((nfo -= mflg) && !stdi) {
- done(0);
- }
- nfo++;
- numtabp[CD].val = stdi = mflg = 0;
- ifile = stdin;
- strcpy(cfname[ifi], "stdin");
- return(0);
- }
- p = (argp++)[0];
- if (rargc >= 0)
- cfname[ifi][0] = 0;
- n1:
- numtabp[CD].val = 0;
- if (p[0] == '-' && p[1] == 0) {
- ifile = stdin;
- strcpy(cfname[ifi], "stdin");
- } else if ((ifile = fopen(p, "r")) == NULL) {
- ERROR "cannot open file %s", p WARN;
- nfo -= mflg;
- done(02);
- } else
- strcpy(cfname[ifi],p);
- nfo++;
- return(0);
- }
- popf(void)
- {
- --ifi;
- if (ifi < 0) {
- ERROR "popf went negative" WARN;
- return 1;
- }
- numtabp[CD].val = cfline[ifi]; /* restore line counter */
- ip = ipl[ifi]; /* input pointer */
- ifile = ifl[ifi]; /* input FILE * */
- return(0);
- }
- void flushi(void)
- {
- if (nflush)
- return;
- ch = 0;
- copyf++;
- while (!nlflg) {
- if (donef && frame == stk)
- break;
- getch();
- }
- copyf--;
- }
- /*
- * return 16-bit, ascii/alphabetic character, ignore chars with more bits,
- * (internal names), spaces and special cookies (below 040).
- * Leave STX ETX ENQ ACK and BELL in to maintain compatibility with v7 troff.
- */
- getach(void)
- {
- Tchar i;
- int j;
- lgf++;
- j = cbits(i = getch());
- if (ismot(i)
- || j > SHORTMASK
- || (j <= 040 && j != 002 /*STX*/
- && j != 003 /*ETX*/
- && j != 005 /*ENQ*/
- && j != 006 /*ACK*/
- && j != 007)) { /*BELL*/
- ch = i;
- j = 0;
- }
- lgf--;
- return j;
- }
- void casenx(void)
- {
- lgf++;
- skip();
- getname();
- nx++;
- if (nmfi > 0)
- nmfi--;
- strcpy(mfiles[nmfi], nextf);
- nextfile();
- nlflg++;
- ip = 0;
- pendt = 0;
- frame = stk;
- nxf = frame + 1;
- }
- getname(void)
- {
- int j, k;
- Tchar i;
- lgf++;
- for (k = 0; k < NS - 1; k++) {
- j = getach();
- if (!j)
- break;
- nextf[k] = j;
- }
- nextf[k] = 0;
- lgf--;
- return(nextf[0]);
- }
- void caseso(void)
- {
- FILE *fp;
- char *p, *q;
- lgf++;
- nextf[0] = 0;
- if (skip() || !getname() || (fp = fopen(nextf, "r")) == NULL || ifi >= NSO) {
- ERROR "can't open file %s", nextf WARN;
- done(02);
- }
- strcpy(cfname[ifi+1], nextf);
- cfline[ifi] = numtabp[CD].val; /*hold line counter*/
- numtabp[CD].val = 0;
- flushi();
- ifl[ifi] = ifile;
- ifile = fp;
- ipl[ifi] = ip;
- ip = 0;
- nx++;
- nflush++;
- ifi++;
- }
- void caself(void) /* set line number and file */
- {
- int n;
- if (skip())
- return;
- n = atoi0();
- if (!nonumb)
- cfline[ifi] = numtabp[CD].val = n - 1;
- if (!skip())
- if (getname()) { /* eats '\n' ? */
- strcpy(cfname[ifi], nextf);
- if (!nonumb)
- numtabp[CD].val--;
- }
- }
- void cpout(FILE *fin, char *token)
- {
- int n;
- char buf[1024];
- if (token) { /* BUG: There should be no NULL bytes in input */
- char *newl = buf;
- while ((fgets(buf, sizeof buf, fin)) != NULL) {
- if (newl) {
- numtabp[CD].val++; /* line number */
- if (strcmp(token, buf) == 0)
- return;
- }
- newl = strchr(buf, '\n');
- fputs(buf, ptid);
- }
- } else {
- while ((n = fread(buf, sizeof *buf, sizeof buf, fin)) > 0)
- fwrite(buf, n, 1, ptid);
- fclose(fin);
- }
- }
- void casecf(void)
- { /* copy file without change */
- FILE *fd;
- char *eof, *p;
- extern int hpos, esc, po;
- /* this may not make much sense in nroff... */
- lgf++;
- nextf[0] = 0;
- if (!skip() && getname()) {
- if (strncmp("<<", nextf, 2) != 0) {
- if ((fd = fopen(nextf, "r")) == NULL) {
- ERROR "can't open file %s", nextf WARN;
- done(02);
- }
- eof = (char *) NULL;
- } else { /* current file */
- if (pbp > lastpbp || ip) {
- ERROR "casecf: not reading from file" WARN;
- done(02);
- }
- eof = &nextf[2];
- if (!*eof) {
- ERROR "casecf: missing end of input token" WARN;
- done(02);
- }
- p = eof;
- while(*++p)
- ;
- *p++ = '\n';
- *p = 0;
- fd = ifile;
- }
- } else {
- ERROR "casecf: no argument" WARN;
- lgf--;
- return;
- }
- lgf--;
- /* make it into a clean state, be sure that everything is out */
- tbreak();
- hpos = po;
- esc = 0;
- ptesc(); /* to left margin */
- esc = un;
- ptesc();
- ptlead();
- ptps();
- ptfont();
- flusho();
- cpout(fd, eof);
- ptps();
- ptfont();
- }
- void getline(char *s, int n) /* get rest of input line into s */
- {
- int i;
- lgf++;
- copyf++;
- skip();
- for (i = 0; i < n-1; i++)
- if ((s[i] = cbits(getch())) == '\n' || s[i] == RIGHT)
- break;
- s[i] = 0;
- copyf--;
- lgf--;
- }
- void casesy(void) /* call system */
- {
- char sybuf[NTM];
- getline(sybuf, NTM);
- system(sybuf);
- }
- void getpn(char *a)
- {
- int n, neg;
- if (*a == 0)
- return;
- neg = 0;
- for ( ; *a; a++)
- switch (*a) {
- case '+':
- case ',':
- continue;
- case '-':
- neg = 1;
- continue;
- default:
- n = 0;
- if (isdigit(*a)) {
- do
- n = 10 * n + *a++ - '0';
- while (isdigit(*a));
- a--;
- } else
- n = 9999;
- *pnp++ = neg ? -n : n;
- neg = 0;
- if (pnp >= &pnlist[NPN-2]) {
- ERROR "too many page numbers" WARN;
- done3(-3);
- }
- }
- if (neg)
- *pnp++ = -9999;
- *pnp = -INT_MAX;
- print = 0;
- pnp = pnlist;
- if (*pnp != -INT_MAX)
- chkpn();
- }
- void setrpt(void)
- {
- Tchar i, j;
- copyf++;
- raw++;
- i = getch0();
- copyf--;
- raw--;
- if ((long) i < 0 || cbits(j = getch0()) == RPT)
- return;
- while (i > 0 && pbp < &pbbuf[NC-3]) {
- i--;
- *pbp++ = j;
- }
- }
|