diff options
author | rsc <devnull@localhost> | 2004-05-15 23:24:00 +0000 |
---|---|---|
committer | rsc <devnull@localhost> | 2004-05-15 23:24:00 +0000 |
commit | 5cedca1b69d020c32466f70843a11767773d7e3b (patch) | |
tree | a15a3d84e92aa262543b0010763a5e6920c9ba24 /src/cmd/troff/n2.c | |
parent | 76e6aca867e3e48ea04fbcf7284c45369a69829e (diff) | |
download | plan9port-5cedca1b69d020c32466f70843a11767773d7e3b.tar.gz plan9port-5cedca1b69d020c32466f70843a11767773d7e3b.tar.bz2 plan9port-5cedca1b69d020c32466f70843a11767773d7e3b.zip |
Let's try this. It's BUGGERED.
Diffstat (limited to 'src/cmd/troff/n2.c')
-rw-r--r-- | src/cmd/troff/n2.c | 325 |
1 files changed, 325 insertions, 0 deletions
diff --git a/src/cmd/troff/n2.c b/src/cmd/troff/n2.c new file mode 100644 index 00000000..8164c038 --- /dev/null +++ b/src/cmd/troff/n2.c @@ -0,0 +1,325 @@ +/* + * 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++; +} |