13e12c5d1SDavid du Colombier /*
23e12c5d1SDavid du Colombier * n2.c
33e12c5d1SDavid du Colombier *
43e12c5d1SDavid du Colombier * output, cleanup
53e12c5d1SDavid du Colombier */
63e12c5d1SDavid du Colombier
73e12c5d1SDavid du Colombier #include "tdef.h"
83e12c5d1SDavid du Colombier #include "fns.h"
93e12c5d1SDavid du Colombier #include "ext.h"
103e12c5d1SDavid du Colombier #include <setjmp.h>
113e12c5d1SDavid du Colombier
12219b2ee8SDavid du Colombier #ifdef STRICT
13219b2ee8SDavid du Colombier /* not in ANSI or POSIX */
14219b2ee8SDavid du Colombier FILE* popen(char*, char*);
15219b2ee8SDavid du Colombier #endif
163e12c5d1SDavid du Colombier
173e12c5d1SDavid du Colombier
183e12c5d1SDavid du Colombier extern jmp_buf sjbuf;
193e12c5d1SDavid du Colombier int toolate;
203e12c5d1SDavid du Colombier int error;
213e12c5d1SDavid du Colombier
223e12c5d1SDavid du Colombier char obuf[2*BUFSIZ];
233e12c5d1SDavid du Colombier char *obufp = obuf;
243e12c5d1SDavid du Colombier
25219b2ee8SDavid du Colombier /* pipe command structure; allows redicously long commends for .pi */
26219b2ee8SDavid du Colombier struct Pipe {
27219b2ee8SDavid du Colombier char *buf;
28219b2ee8SDavid du Colombier int tick;
29219b2ee8SDavid du Colombier int cnt;
30219b2ee8SDavid du Colombier } Pipe;
31219b2ee8SDavid du Colombier
32219b2ee8SDavid du Colombier
333e12c5d1SDavid du Colombier int xon = 0; /* records if in middle of \X */
343e12c5d1SDavid du Colombier
pchar(Tchar i)353e12c5d1SDavid du Colombier int pchar(Tchar i)
363e12c5d1SDavid du Colombier {
373e12c5d1SDavid du Colombier int j;
383e12c5d1SDavid du Colombier static int hx = 0; /* records if have seen HX */
393e12c5d1SDavid du Colombier
403e12c5d1SDavid du Colombier if (hx) {
413e12c5d1SDavid du Colombier hx = 0;
423e12c5d1SDavid du Colombier j = absmot(i);
433e12c5d1SDavid du Colombier if (isnmot(i)) {
443e12c5d1SDavid du Colombier if (j > dip->blss)
453e12c5d1SDavid du Colombier dip->blss = j;
463e12c5d1SDavid du Colombier } else {
473e12c5d1SDavid du Colombier if (j > dip->alss)
483e12c5d1SDavid du Colombier dip->alss = j;
493e12c5d1SDavid du Colombier ralss = dip->alss;
503e12c5d1SDavid du Colombier }
513e12c5d1SDavid du Colombier return 0;
523e12c5d1SDavid du Colombier }
533e12c5d1SDavid du Colombier if (ismot(i)) {
543e12c5d1SDavid du Colombier pchar1(i);
553e12c5d1SDavid du Colombier return 0;
563e12c5d1SDavid du Colombier }
573e12c5d1SDavid du Colombier switch (j = cbits(i)) {
583e12c5d1SDavid du Colombier case 0:
593e12c5d1SDavid du Colombier case IMP:
603e12c5d1SDavid du Colombier case RIGHT:
613e12c5d1SDavid du Colombier case LEFT:
623e12c5d1SDavid du Colombier return 0;
633e12c5d1SDavid du Colombier case HX:
643e12c5d1SDavid du Colombier hx = 1;
653e12c5d1SDavid du Colombier return 0;
663e12c5d1SDavid du Colombier case XON:
673e12c5d1SDavid du Colombier xon++;
683e12c5d1SDavid du Colombier break;
693e12c5d1SDavid du Colombier case XOFF:
703e12c5d1SDavid du Colombier xon--;
713e12c5d1SDavid du Colombier break;
723e12c5d1SDavid du Colombier case PRESC:
733e12c5d1SDavid du Colombier if (!xon && !tflg && dip == &d[0])
743e12c5d1SDavid du Colombier j = eschar; /* fall through */
753e12c5d1SDavid du Colombier default:
763e12c5d1SDavid du Colombier setcbits(i, trtab[j]);
773e12c5d1SDavid du Colombier }
78*223a736eSDavid du Colombier if (NROFF & xon) /* rob fix for man2html */
79*223a736eSDavid du Colombier return 0;
803e12c5d1SDavid du Colombier pchar1(i);
813e12c5d1SDavid du Colombier return 0;
823e12c5d1SDavid du Colombier }
833e12c5d1SDavid du Colombier
843e12c5d1SDavid du Colombier
pchar1(Tchar i)853e12c5d1SDavid du Colombier void pchar1(Tchar i)
863e12c5d1SDavid du Colombier {
873e12c5d1SDavid du Colombier int j;
883e12c5d1SDavid du Colombier
893e12c5d1SDavid du Colombier j = cbits(i);
903e12c5d1SDavid du Colombier if (dip != &d[0]) {
913e12c5d1SDavid du Colombier wbf(i);
923e12c5d1SDavid du Colombier dip->op = offset;
933e12c5d1SDavid du Colombier return;
943e12c5d1SDavid du Colombier }
953e12c5d1SDavid du Colombier if (!tflg && !print) {
963e12c5d1SDavid du Colombier if (j == '\n')
973e12c5d1SDavid du Colombier dip->alss = dip->blss = 0;
983e12c5d1SDavid du Colombier return;
993e12c5d1SDavid du Colombier }
1003e12c5d1SDavid du Colombier if (j == FILLER && !xon)
1013e12c5d1SDavid du Colombier return;
1023e12c5d1SDavid du Colombier if (tflg) { /* transparent mode, undiverted */
1033e12c5d1SDavid du Colombier if (print) /* assumes that it's ok to print */
1043e12c5d1SDavid du Colombier /* OUT "%c", j PUT; /* i.e., is ascii */
1053e12c5d1SDavid du Colombier outascii(i);
1063e12c5d1SDavid du Colombier return;
1073e12c5d1SDavid du Colombier }
1083e12c5d1SDavid du Colombier if (TROFF && ascii)
1093e12c5d1SDavid du Colombier outascii(i);
1103e12c5d1SDavid du Colombier else
1113e12c5d1SDavid du Colombier ptout(i);
1123e12c5d1SDavid du Colombier }
1133e12c5d1SDavid du Colombier
1143e12c5d1SDavid du Colombier
outweird(int k)115219b2ee8SDavid du Colombier void outweird(int k) /* like ptchname() but ascii */
116219b2ee8SDavid du Colombier {
117219b2ee8SDavid du Colombier char *chn = chname(k);
118219b2ee8SDavid du Colombier
119219b2ee8SDavid du Colombier switch (chn[0]) {
120219b2ee8SDavid du Colombier case MBchar:
121219b2ee8SDavid du Colombier OUT "%s", chn+1 PUT; /* \n not needed? */
122219b2ee8SDavid du Colombier break;
123219b2ee8SDavid du Colombier case Number:
124219b2ee8SDavid du Colombier OUT "\\N'%s'", chn+1 PUT;
125219b2ee8SDavid du Colombier break;
126219b2ee8SDavid du Colombier case Troffchar:
127219b2ee8SDavid du Colombier if (strlen(chn+1) == 2)
128219b2ee8SDavid du Colombier OUT "\\(%s", chn+1 PUT;
129219b2ee8SDavid du Colombier else
130219b2ee8SDavid du Colombier OUT "\\C'%s'", chn+1 PUT;
131219b2ee8SDavid du Colombier break;
132219b2ee8SDavid du Colombier default:
133219b2ee8SDavid du Colombier OUT " %s? ", chn PUT;
134219b2ee8SDavid du Colombier break;
135219b2ee8SDavid du Colombier }
136219b2ee8SDavid du Colombier }
137219b2ee8SDavid du Colombier
outascii(Tchar i)1383e12c5d1SDavid du Colombier void outascii(Tchar i) /* print i in best-guess ascii */
1393e12c5d1SDavid du Colombier {
1403e12c5d1SDavid du Colombier int j = cbits(i);
1413e12c5d1SDavid du Colombier
1423e12c5d1SDavid du Colombier /* is this ever called with NROFF set? probably doesn't work at all. */
1433e12c5d1SDavid du Colombier
1443e12c5d1SDavid du Colombier if (ismot(i))
1453e12c5d1SDavid du Colombier oput(' ');
1463e12c5d1SDavid du Colombier else if (j < ALPHABET && j >= ' ' || j == '\n' || j == '\t')
1473e12c5d1SDavid du Colombier oput(j);
1483e12c5d1SDavid du Colombier else if (j == DRAWFCN)
1493e12c5d1SDavid du Colombier oputs("\\D");
1503e12c5d1SDavid du Colombier else if (j == HYPHEN)
1513e12c5d1SDavid du Colombier oput('-');
1523e12c5d1SDavid du Colombier else if (j == MINUS) /* special pleading for strange encodings */
1533e12c5d1SDavid du Colombier oputs("\\-");
1543e12c5d1SDavid du Colombier else if (j == PRESC)
1553e12c5d1SDavid du Colombier oputs("\\e");
1563e12c5d1SDavid du Colombier else if (j == FILLER)
1573e12c5d1SDavid du Colombier oputs("\\&");
1583e12c5d1SDavid du Colombier else if (j == UNPAD)
1593e12c5d1SDavid du Colombier oputs("\\ ");
1603e12c5d1SDavid du Colombier else if (j == OHC) /* this will never occur; stripped out earlier */
1613e12c5d1SDavid du Colombier oputs("\\%");
1623e12c5d1SDavid du Colombier else if (j == XON)
1633e12c5d1SDavid du Colombier oputs("\\X");
1643e12c5d1SDavid du Colombier else if (j == XOFF)
1653e12c5d1SDavid du Colombier oputs(" ");
1663e12c5d1SDavid du Colombier else if (j == LIG_FI)
1673e12c5d1SDavid du Colombier oputs("fi");
1683e12c5d1SDavid du Colombier else if (j == LIG_FL)
1693e12c5d1SDavid du Colombier oputs("fl");
1703e12c5d1SDavid du Colombier else if (j == LIG_FF)
1713e12c5d1SDavid du Colombier oputs("ff");
1723e12c5d1SDavid du Colombier else if (j == LIG_FFI)
1733e12c5d1SDavid du Colombier oputs("ffi");
1743e12c5d1SDavid du Colombier else if (j == LIG_FFL)
1753e12c5d1SDavid du Colombier oputs("ffl");
1763e12c5d1SDavid du Colombier else if (j == WORDSP) { /* nothing at all */
1773e12c5d1SDavid du Colombier if (xon) /* except in \X */
1783e12c5d1SDavid du Colombier oput(' ');
179219b2ee8SDavid du Colombier
1803e12c5d1SDavid du Colombier } else
1813e12c5d1SDavid du Colombier outweird(j);
1823e12c5d1SDavid du Colombier }
1833e12c5d1SDavid du Colombier
flusho(void)1843e12c5d1SDavid du Colombier int flusho(void)
1853e12c5d1SDavid du Colombier {
186219b2ee8SDavid du Colombier if (NROFF && !toolate && t.twinit)
1873e12c5d1SDavid du Colombier fwrite(t.twinit, strlen(t.twinit), 1, ptid);
1883e12c5d1SDavid du Colombier
1893e12c5d1SDavid du Colombier if (obufp > obuf) {
190219b2ee8SDavid du Colombier if (pipeflg && !toolate) {
191219b2ee8SDavid du Colombier /* fprintf(stderr, "Pipe to <%s>\n", Pipe.buf); */
192219b2ee8SDavid du Colombier if (!Pipe.buf[0] || (ptid = popen(Pipe.buf, "w")) == NULL)
193219b2ee8SDavid du Colombier ERROR "pipe %s not created.", Pipe.buf WARN;
194219b2ee8SDavid du Colombier if (Pipe.buf)
195219b2ee8SDavid du Colombier free(Pipe.buf);
196219b2ee8SDavid du Colombier }
197219b2ee8SDavid du Colombier if (!toolate)
198219b2ee8SDavid du Colombier toolate++;
1993e12c5d1SDavid du Colombier *obufp = 0;
2003e12c5d1SDavid du Colombier fputs(obuf, ptid);
2013e12c5d1SDavid du Colombier fflush(ptid);
2023e12c5d1SDavid du Colombier obufp = obuf;
2033e12c5d1SDavid du Colombier }
2043e12c5d1SDavid du Colombier return 1;
2053e12c5d1SDavid du Colombier }
2063e12c5d1SDavid du Colombier
2073e12c5d1SDavid du Colombier
caseex(void)2083e12c5d1SDavid du Colombier void caseex(void)
2093e12c5d1SDavid du Colombier {
2103e12c5d1SDavid du Colombier done(0);
2113e12c5d1SDavid du Colombier }
2123e12c5d1SDavid du Colombier
2133e12c5d1SDavid du Colombier
done(int x)2143e12c5d1SDavid du Colombier void done(int x)
2153e12c5d1SDavid du Colombier {
2163e12c5d1SDavid du Colombier int i;
2173e12c5d1SDavid du Colombier
2183e12c5d1SDavid du Colombier error |= x;
2193e12c5d1SDavid du Colombier app = ds = lgf = 0;
2203e12c5d1SDavid du Colombier if (i = em) {
2213e12c5d1SDavid du Colombier donef = -1;
222219b2ee8SDavid du Colombier eschar = '\\';
2233e12c5d1SDavid du Colombier em = 0;
2243e12c5d1SDavid du Colombier if (control(i, 0))
2253e12c5d1SDavid du Colombier longjmp(sjbuf, 1);
2263e12c5d1SDavid du Colombier }
2273e12c5d1SDavid du Colombier if (!nfo)
2283e12c5d1SDavid du Colombier done3(0);
2293e12c5d1SDavid du Colombier mflg = 0;
2303e12c5d1SDavid du Colombier dip = &d[0];
2313e12c5d1SDavid du Colombier if (woff) /* BUG!!! This isn't set anywhere */
2323e12c5d1SDavid du Colombier wbf((Tchar)0);
2333e12c5d1SDavid du Colombier if (pendw)
2343e12c5d1SDavid du Colombier getword(1);
2353e12c5d1SDavid du Colombier pendnf = 0;
2363e12c5d1SDavid du Colombier if (donef == 1)
2373e12c5d1SDavid du Colombier done1(0);
2383e12c5d1SDavid du Colombier donef = 1;
2393e12c5d1SDavid du Colombier ip = 0;
2403e12c5d1SDavid du Colombier frame = stk;
2413e12c5d1SDavid du Colombier nxf = frame + 1;
2423e12c5d1SDavid du Colombier if (!ejf)
2433e12c5d1SDavid du Colombier tbreak();
2443e12c5d1SDavid du Colombier nflush++;
2453e12c5d1SDavid du Colombier eject((Stack *)0);
2463e12c5d1SDavid du Colombier longjmp(sjbuf, 1);
2473e12c5d1SDavid du Colombier }
2483e12c5d1SDavid du Colombier
2493e12c5d1SDavid du Colombier
done1(int x)2503e12c5d1SDavid du Colombier void done1(int x)
2513e12c5d1SDavid du Colombier {
2523e12c5d1SDavid du Colombier error |= x;
253219b2ee8SDavid du Colombier if (numtabp[NL].val) {
2543e12c5d1SDavid du Colombier trap = 0;
2553e12c5d1SDavid du Colombier eject((Stack *)0);
2563e12c5d1SDavid du Colombier longjmp(sjbuf, 1);
2573e12c5d1SDavid du Colombier }
2583e12c5d1SDavid du Colombier if (!ascii)
2593e12c5d1SDavid du Colombier pttrailer();
2603e12c5d1SDavid du Colombier done2(0);
2613e12c5d1SDavid du Colombier }
2623e12c5d1SDavid du Colombier
2633e12c5d1SDavid du Colombier
done2(int x)2643e12c5d1SDavid du Colombier void done2(int x)
2653e12c5d1SDavid du Colombier {
2663e12c5d1SDavid du Colombier ptlead();
2673e12c5d1SDavid du Colombier if (TROFF && !ascii)
2683e12c5d1SDavid du Colombier ptstop();
2693e12c5d1SDavid du Colombier flusho();
2703e12c5d1SDavid du Colombier done3(x);
2713e12c5d1SDavid du Colombier }
2723e12c5d1SDavid du Colombier
done3(int x)2733e12c5d1SDavid du Colombier void done3(int x)
2743e12c5d1SDavid du Colombier {
2753e12c5d1SDavid du Colombier error |= x;
2763e12c5d1SDavid du Colombier flusho();
2773e12c5d1SDavid du Colombier if (NROFF)
2783e12c5d1SDavid du Colombier twdone();
2793e12c5d1SDavid du Colombier if (pipeflg)
2803e12c5d1SDavid du Colombier pclose(ptid);
2813e12c5d1SDavid du Colombier exit(error);
2823e12c5d1SDavid du Colombier }
2833e12c5d1SDavid du Colombier
2843e12c5d1SDavid du Colombier
edone(int x)2853e12c5d1SDavid du Colombier void edone(int x)
2863e12c5d1SDavid du Colombier {
2873e12c5d1SDavid du Colombier frame = stk;
2883e12c5d1SDavid du Colombier nxf = frame + 1;
2893e12c5d1SDavid du Colombier ip = 0;
2903e12c5d1SDavid du Colombier done(x);
2913e12c5d1SDavid du Colombier }
2923e12c5d1SDavid du Colombier
2933e12c5d1SDavid du Colombier
casepi(void)2943e12c5d1SDavid du Colombier void casepi(void)
2953e12c5d1SDavid du Colombier {
296219b2ee8SDavid du Colombier int j;
2973e12c5d1SDavid du Colombier char buf[NTM];
2983e12c5d1SDavid du Colombier
299219b2ee8SDavid du Colombier if (Pipe.buf == NULL) {
300219b2ee8SDavid du Colombier if ((Pipe.buf = (char *)calloc(NTM, sizeof(char))) == NULL) {
301219b2ee8SDavid du Colombier ERROR "No buf space for pipe cmd" WARN;
3023e12c5d1SDavid du Colombier return;
3033e12c5d1SDavid du Colombier }
304219b2ee8SDavid du Colombier Pipe.tick = 1;
305219b2ee8SDavid du Colombier } else
306219b2ee8SDavid du Colombier Pipe.buf[Pipe.cnt++] = '|';
307219b2ee8SDavid du Colombier
308219b2ee8SDavid du Colombier getline(buf, NTM);
309219b2ee8SDavid du Colombier j = strlen(buf);
310219b2ee8SDavid du Colombier if (toolate) {
311219b2ee8SDavid du Colombier ERROR "Cannot create pipe to %s", buf WARN;
312219b2ee8SDavid du Colombier return;
313219b2ee8SDavid du Colombier }
314219b2ee8SDavid du Colombier Pipe.cnt += j;
315219b2ee8SDavid du Colombier if (j >= NTM +1) {
316219b2ee8SDavid du Colombier Pipe.tick++;
317219b2ee8SDavid du Colombier if ((Pipe.buf = (char *)realloc(Pipe.buf, Pipe.tick * NTM * sizeof(char))) == NULL) {
318219b2ee8SDavid du Colombier ERROR "No more buf space for pipe cmd" WARN;
319219b2ee8SDavid du Colombier return;
320219b2ee8SDavid du Colombier }
321219b2ee8SDavid du Colombier }
322219b2ee8SDavid du Colombier strcat(Pipe.buf, buf);
3233e12c5d1SDavid du Colombier pipeflg++;
3243e12c5d1SDavid du Colombier }
325