aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/troff/n2.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/troff/n2.c')
-rw-r--r--src/cmd/troff/n2.c325
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++;
+}