📄 n1.c
字号:
/* * 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 "???"#endifchar *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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -