ref: 9ced712a2ad70557a8ceb89ff3b969b92c85f68c
dir: /sys/src/cmd/troff/n2.c/
/* * n2.c * * output, cleanup */ #include "tdef.h" #include "fns.h" #include "ext.h" #include <setjmp.h> #ifdef STRICT /* not in ANSI or POSIX */ FILE* popen(char*, char*); #endif extern jmp_buf sjbuf; int toolate; int error; char obuf[2*BUFSIZ]; char *obufp = obuf; /* pipe command structure; allows redicously long commends for .pi */ struct Pipe { char *buf; int tick; int cnt; } Pipe; int xon = 0; /* records if in middle of \X */ int pchar(Tchar i) { int j; static int hx = 0; /* records if have seen HX */ if (hx) { hx = 0; j = absmot(i); if (isnmot(i)) { if (j > dip->blss) dip->blss = j; } else { if (j > dip->alss) dip->alss = j; ralss = dip->alss; } return 0; } if (ismot(i)) { pchar1(i); return 0; } switch (j = cbits(i)) { case 0: case IMP: case RIGHT: case LEFT: return 0; case HX: hx = 1; return 0; case XON: xon++; break; case XOFF: xon--; break; case PRESC: if (!xon && !tflg && dip == &d[0]) j = eschar; /* fall through */ default: setcbits(i, trtab[j]); } if (NROFF & xon) /* rob fix for man2html */ return 0; pchar1(i); return 0; } void pchar1(Tchar i) { int j; j = cbits(i); if (dip != &d[0]) { wbf(i); dip->op = offset; return; } if (!tflg && !print) { if (j == '\n') dip->alss = dip->blss = 0; return; } if (j == FILLER && !xon) return; if (tflg) { /* transparent mode, undiverted */ if (print) /* assumes that it's ok to print */ /* OUT "%c", j PUT; /* i.e., is ascii */ outascii(i); return; } if (TROFF && ascii) outascii(i); else ptout(i); } void outweird(int k) /* like ptchname() but ascii */ { char *chn = chname(k); switch (chn[0]) { case MBchar: OUT "%s", chn+1 PUT; /* \n not needed? */ break; case Number: OUT "\\N'%s'", chn+1 PUT; break; case Troffchar: if (strlen(chn+1) == 2) OUT "\\(%s", chn+1 PUT; else OUT "\\C'%s'", chn+1 PUT; break; default: OUT " %s? ", chn PUT; break; } } void outascii(Tchar i) /* print i in best-guess ascii */ { char *p; int j = cbits(i); /* is this ever called with NROFF set? probably doesn't work at all. */ if (ismot(i)) oput(' '); else if (j < ALPHABET && j >= ' ' || j == '\n' || j == '\t') oput(j); else if (j == DRAWFCN) oputs("\\D"); else if (j == HYPHEN) oput('-'); else if (j == MINUS) /* special pleading for strange encodings */ oputs("\\-"); else if (j == PRESC) oputs("\\e"); else if (j == FILLER) oputs("\\&"); else if (j == UNPAD) oputs("\\ "); else if (j == OHC) /* this will never occur; stripped out earlier */ oputs("\\%"); else if (j == XON) oputs("\\X"); else if (j == XOFF) oputs(" "); else if (j == LIG_FI) oputs("fi"); else if (j == LIG_FL) oputs("fl"); else if (j == LIG_FF) oputs("ff"); else if (j == LIG_FFI) oputs("ffi"); else if (j == LIG_FFL) oputs("ffl"); else if (j == WORDSP) { /* nothing at all */ if (xon) /* except in \X */ oput(' '); } else outweird(j); } int flusho(void) { if (NROFF && !toolate && t.twinit) fwrite(t.twinit, strlen(t.twinit), 1, ptid); if (obufp > obuf) { if (pipeflg && !toolate) { /* fprintf(stderr, "Pipe to <%s>\n", Pipe.buf); */ if (!Pipe.buf[0] || (ptid = popen(Pipe.buf, "w")) == NULL) ERROR "pipe %s not created.", Pipe.buf WARN; if (Pipe.buf) free(Pipe.buf); } if (!toolate) toolate++; *obufp = 0; fputs(obuf, ptid); fflush(ptid); obufp = obuf; } return 1; } void caseex(void) { done(0); } void done(int x) { int i; error |= x; app = ds = lgf = 0; if (i = em) { donef = -1; eschar = '\\'; em = 0; if (control(i, 0)) longjmp(sjbuf, 1); } if (!nfo) done3(0); mflg = 0; dip = &d[0]; if (woff) /* BUG!!! This isn't set anywhere */ wbf((Tchar)0); if (pendw) getword(1); pendnf = 0; if (donef == 1) done1(0); donef = 1; ip = 0; frame = stk; nxf = frame + 1; if (!ejf) tbreak(); nflush++; eject((Stack *)0); longjmp(sjbuf, 1); } void done1(int x) { error |= x; if (numtabp[NL].val) { trap = 0; eject((Stack *)0); longjmp(sjbuf, 1); } if (!ascii) pttrailer(); done2(0); } void done2(int x) { ptlead(); if (TROFF && !ascii) ptstop(); flusho(); done3(x); } void done3(int x) { error |= x; flusho(); if (NROFF) twdone(); if (pipeflg) pclose(ptid); exit(error); } void edone(int x) { frame = stk; nxf = frame + 1; ip = 0; done(x); } void casepi(void) { int j; char buf[NTM]; if (Pipe.buf == NULL) { if ((Pipe.buf = (char *)calloc(NTM, sizeof(char))) == NULL) { ERROR "No buf space for pipe cmd" WARN; return; } Pipe.tick = 1; } else Pipe.buf[Pipe.cnt++] = '|'; getline(buf, NTM); j = strlen(buf); if (toolate) { ERROR "Cannot create pipe to %s", buf WARN; return; } Pipe.cnt += j; if (j >= NTM +1) { Pipe.tick++; if ((Pipe.buf = (char *)realloc(Pipe.buf, Pipe.tick * NTM * sizeof(char))) == NULL) { ERROR "No more buf space for pipe cmd" WARN; return; } } strcat(Pipe.buf, buf); pipeflg++; }