📄 roff.c
字号:
int f; f = *i = *s = 0; for (;;) { c = suck(); if (c == EOF || c == '\n') break; if (isspace(c)) { if (f) break; else continue; } if (isdigit(c)) { f++; *i = *i * 10 + c - '0'; } else if ((c == '+' || c == '-') && !f) { f++; *s = c == '+' ? 1 : -1; } else break; } while (c != EOF && c != '\n') c = suck(); if (!f) { *i = 1; *s = sdef; } return c;}int cread(k)int *k;{ int u; *k = -1; for (;;) { u = suck(); if (u == EOF || u == '\n') return u; if (isspace(u)) continue; if (*k < 0) *k = u; }}void defmac(){ int i; char newmac[3], *nm; if (skipsp()) return; nm = newmac; if (!Macwrite) openmac(); *nm++ = suck(); c = suck(); if (c != EOF && c != '\n' && c != ' ' && c != '\t') *nm++ = c; *nm = '\0'; /* KILL OLD DEFINITION IF ANY */ for (i = 0; i < n_macros; i++) if (!strcmp(newmac, macro[i].mname)) { macro[i].mname[0] = '\0'; break; } macro[n_macros].moff = ftell(Macwrite); strcpy(macro[n_macros++].mname, newmac); while (c != EOF && c != '\n') c = suck(); /* FLUSH HEADER LINE */ while (copyline()); fflush(Macwrite);}void openmac(){ if (NULL == (Macwrite = fopen(mktemp(mfilnam), "w"))) { fprintf(stderr, "roff: cannot open temp file\n"); exit(1); } Macread = fopen(mfilnam, "r"); unlink(mfilnam);}int copyline(){ int n, first, second; if (c == EOF) { fprintf(Macwrite, "..\n"); return 0; } n = 0; first = 1; second = 0; for (;;) { c = suck(); if (c == EOF) { if (!first) putc('\n', Macwrite); return 0; } if (c == '\n') { putc('\n', Macwrite); return n != 2; } if (first && c == '.') n++; else if (second && n == 1 && c == '.') n++; putc(c, Macwrite); second = first; first = 0; }}void submac(r)int r;{ while (c != EOF && c != '\n') c = suck(); if (depth) teller[depth - 1] = ftell(Macread); else { Save = File; File = Macread; } depth++; fseek(Macread, macro[r].moff, 0);}void endmac(){ depth--; if (depth) fseek(Macread, teller[depth - 1], 0); else File = Save; c = '\n';}void do_ta(){ int v; n_ta = 0; for (;;) { nread(&v); if (v == 1) return; else o_ta[n_ta++] = v; if (c == '\n' || c == EOF) break; }}void do_tr(){ char *t; t = &o_tr[0][0]; *t = '\0'; if (skipsp()) return; for (;;) { c = suck(); if (c == EOF || c == '\n') break; *t++ = c; } *t = '\0';}void do_nx(){ char fname[100], *f; f = fname; if (skipsp()) return; for (;;) switch (c = suck()) { case EOF: case '\n': case ' ': case '\t': if (f == fname) return; goto got_nx; default: *f++ = c; }got_nx: fclose(File); *f = '\0'; if (!(File = fopen(fname, "r"))) { fprintf(stderr, "roff: cannot read %s\n", fname); exit(1); }}int skipsp(){ for (;;) switch (c = suck()) { case EOF: case '\n': return 1; case ' ': case '\t': continue; default: ungetc(c, File); return 0; }}void writebreak(){ int q; if (assylen) writeline(0, 1); q = TXTLEN; if (o_bl) { if (o_bl + line_no > q) { endpage(); beginpage(); } for (; o_bl; o_bl--) blankline(); } else if (o_sp) { if (o_sp + line_no > q) newpage(); else if (line_no) for (; o_sp; o_sp--) blankline(); }}void blankline(){ if (line_no >= TXTLEN) newpage(); if (o_n2) o_n2++; spit('\n'); line_no++;}void writeline(adflag, flushflag)int adflag, flushflag;{ int j, q; char lnstring[7]; for (j = assylen - 1; j; j--) { if (assyline[j] == ' ') assylen--; else break; } q = TXTLEN; if (line_no >= q) newpage(); for (j = 0; j < o_po; j++) spit(' '); if (o_n1) { if (o_nn) for (j = 0; j < o_ni + 4; j++) spit(' '); else { for (j = 0; j < o_ni; j++) spit(' '); sprintf(lnstring, "%3d ", line_no + 1); spits(lnstring); } } if (o_n2) { if (o_nn) for (j = 0; j < o_ni + 4; j++) spit(' '); else { for (j = 0; j < o_ni; j++) spit(' '); sprintf(lnstring, "%3d ", o_n2++); spits(lnstring); } } if (o_nn) o_nn--; if (o_ce) for (j = 0; j < (o_ll - assylen + 1) / 2; j++) spit(' '); else for (j = 0; j < IDTLEN; j++) spit(' '); if (adflag && !flushflag) fillline(); for (j = 0; j < assylen; j++) spit(assyline[j]); spit('\n'); assylen = 0; assyline[0] = '\0'; line_no++; for (j = 1; j < o_ls; j++) if (line_no <= q) blankline(); if (!flushflag) { if (o_hc) dehyph(holdword); strcpy(assyline, holdword); assylen = strlen(holdword); *holdword = '\0'; holdp = holdword; } if (o_ix >= 0) o_in = o_ix; o_ix = o_ti = -1;}void fillline(){ int excess, j, s, inc, spaces; adjtoggle ^= 1; if (!(excess = o_ll - IDTLEN - assylen)) return; if (excess < 0) { fprintf(stderr, "roff: internal error #2 [%d]\n", excess); exit(1); } for (j = 2;; j++) { if (adjtoggle) { s = 0; inc = 1; } else { s = assylen - 1; inc = -1; } spaces = 0; while (s >= 0 && s < assylen) { if (assyline[s] == ' ') spaces++; else { if (0 < spaces && spaces < j) { insrt(s - inc); if (inc > 0) s++; if (!--excess) return; } spaces = 0; } s += inc; } }}void insrt(p)int p;{ int i; for (i = assylen; i > p; i--) assyline[i] = assyline[i - 1]; assylen++;}void newpage(){ if (page_no >= 0) endpage(); else page_no = 1; for (; o_sk; o_sk--) blankpage(); beginpage();}void beginpage(){ int i; if (sflag) waitawhile(); for (i = 0; i < o_m1; i++) spit('\n'); writetitle(page_no & 1 ? ohead : ehead); for (i = 0; i < o_m2; i++) spit('\n'); line_no = 0;}void endpage(){ int i; for (i = line_no; i < TXTLEN; i++) blankline(); for (i = 0; i < o_m3; i++) spit('\n'); writetitle(page_no & 1 ? ofoot : efoot); for (i = 0; i < o_m4; i++) spit('\n'); if (o_bp < 0) page_no++; else { page_no = o_bp; o_bp = -1; }}void blankpage(){ int i; if (sflag) waitawhile(); for (i = 0; i < o_m1; i++) spit('\n'); writetitle(page_no & 1 ? ohead : ehead); for (i = 0; i < o_m2; i++) spit('\n'); for (i = 0; i < TXTLEN; i++) spit('\n'); for (i = 0; i < o_m3; i++) spit('\n'); writetitle(page_no & 1 ? ofoot : efoot); page_no++; for (i = 0; i < o_m4; i++) spit('\n'); line_no = 0;}void waitawhile(){ tcflag_t oldflags; if (isatty(0)) { oldflags = tty.c_lflag; tty.c_lflag &= ~ECHO; /* DON'T ECHO THE RUBOUT */ tcsetattr(0, TCSANOW, &tty); } signal(SIGINT, nix); pause(); if (isatty(0)) { tty.c_lflag = oldflags; tcsetattr(0, TCSANOW, &tty); }}void nix(sig)int sig;{}void writetitle(t)char *t;{ char d, *pst; int j, l, m, n; d = *t; if (o_hx || !d) { spit('\n'); return; } pst = pgform(); for (j = 0; j < o_po; j++) spit(' '); l = titlen(++t, d, strlen(pst)); while (*t && *t != d) { if (*t == '%') spits(pst); else spit(*t); t++; } if (!*t) { spit('\n'); return; } m = titlen(++t, d, strlen(pst)); for (j = l; j < (o_ll - m) / 2; j++) spit(' '); while (*t && *t != d) { if (*t == '%') spits(pst); else spit(*t); t++; } if (!*t) { spit('\n'); return; } if ((o_ll - m) / 2 > l) m += (o_ll - m) / 2; else m += l; n = titlen(++t, d, strlen(pst)); for (j = m; j < o_ll - n; j++) spit(' '); while (*t && *t != d) { if (*t == '%') spits(pst); else spit(*t); t++; } spit('\n');}char * pgform(){ static char pst[11]; int i; if (o_ro) { *pst = '\0'; i = page_no; if (i >= 400) { strcat(pst, "cd"); i -= 400; } while (i >= 100) { strcat(pst, "c"); i -= 100; } if (i >= 90) { strcat(pst, "xc"); i -= 90; } if (i >= 50) { strcat(pst, "l"); i -= 50; } if (i >= 40) { strcat(pst, "xl"); i -= 40; } while (i >= 10) { strcat(pst, "x"); i -= 10; } if (i >= 9) { strcat(pst, "ix"); i -= 9; } if (i >= 5) { strcat(pst, "v"); i -= 5; } if (i >= 4) { strcat(pst, "iv"); i -= 4; } while (i--) strcat(pst, "i"); } else sprintf(pst, "%d", page_no); return pst;}int titlen(t, c, k)char *t, c;int k;{ int q; q = 0; while (*t && *t != c) q += *t++ == '%' ? k : 1; return q;}void spits(s)char *s;{ while (*s) spit(*s++);}void spit(c)char c;{ static int col_no, n_blanks; int ulflag; char *t; ulflag = c & UNDERL; c &= ~UNDERL; for (t = (char *) o_tr; *t; t++) if (*t++ == c) {/* * fix - last char translates to space. */ c = *t ? *t : ' '; break; } if (page_no < startpage || (stoppage && page_no > stoppage)) return; if (c != ' ' && c != '\n' && n_blanks) { if (hflag && n_blanks > 1) while (col_no / 8 < (col_no + n_blanks) / 8) { putc('\t', stdout); n_blanks -= 8 - (col_no & 07); col_no = (8 + col_no) & ~07; } for (; n_blanks; n_blanks--) { putc(' ', stdout); col_no++; } } if (ulflag && isalnum(c)) fputs("_\b", stdout); if (c == ' ') n_blanks++; else { putc(c, stdout); col_no++; } if (c == '\n') { col_no = 0; n_blanks = 0; }}int suck(){ for (;;) { c = getc(File); if (islegal(c)) return c; }}/* * strhas - does string have character? Allow UNDERL flag. */char * strhas(p, c)char *p, c;{ for (; *p; p++) if ((*p & ~UNDERL) == c) return p; return NULL;}/* * strend - find NULL at end of string. */char * strend(p)char *p;{ while (*p++); return p;}/* * isspace, isalnum, isdigit, islegal - classify a character. * We could just as well use <ctype.h> if it didn't vary from * one version of Unix to another. As it is, these routines * must be modified for weird character sets, like EBCDIC and * CDC Scientific. */int isspace(c)int c;{ char *s; for (s = spacechars; *s; s++) if (*s == c) return 1; return 0;}int isalnum(c)int c;{ return(c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9');}int isdigit(c)int c;{ return c >= '0' && c <= '9';}int islegal(c)int c;{ return (c >= ' ' && c <= '~') || isspace(c) || c == '\n' || c == EOF;}void bomb(){ fprintf(stderr, "Usage: roff [+00] [-00] [-s] [-h] file ...\n"); exit(1);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -