Blob


1 /*
2 * n2.c
3 *
4 * output, cleanup
5 */
7 #define _BSD_SOURCE 1 /* popen */
8 #include "tdef.h"
9 #include "fns.h"
10 #include "ext.h"
11 #include <setjmp.h>
13 #ifdef STRICT
14 /* not in ANSI or POSIX */
15 FILE* popen(char*, char*);
16 #endif
19 extern jmp_buf sjbuf;
20 int toolate;
21 int error;
23 char obuf[2*BUFSIZ];
24 char *obufp = obuf;
26 /* pipe command structure; allows redicously long commends for .pi */
27 struct Pipe {
28 char *buf;
29 int tick;
30 int cnt;
31 } Pipe;
34 int xon = 0; /* records if in middle of \X */
36 int pchar(Tchar i)
37 {
38 int j;
39 static int hx = 0; /* records if have seen HX */
41 if (hx) {
42 hx = 0;
43 j = absmot(i);
44 if (isnmot(i)) {
45 if (j > dip->blss)
46 dip->blss = j;
47 } else {
48 if (j > dip->alss)
49 dip->alss = j;
50 ralss = dip->alss;
51 }
52 return 0;
53 }
54 if (ismot(i)) {
55 pchar1(i);
56 return 0;
57 }
58 switch (j = cbits(i)) {
59 case 0:
60 case IMP:
61 case RIGHT:
62 case LEFT:
63 return 0;
64 case HX:
65 hx = 1;
66 return 0;
67 case XON:
68 xon++;
69 break;
70 case XOFF:
71 xon--;
72 break;
73 case PRESC:
74 if (!xon && !tflg && dip == &d[0])
75 j = eschar; /* fall through */
76 default:
77 setcbits(i, trtab[j]);
78 }
79 if (NROFF & xon) /* rob fix for man2html */
80 return 0;
81 pchar1(i);
82 return 0;
83 }
86 void pchar1(Tchar i)
87 {
88 int j;
90 j = cbits(i);
91 if (dip != &d[0]) {
92 wbf(i);
93 dip->op = offset;
94 return;
95 }
96 if (!tflg && !print) {
97 if (j == '\n')
98 dip->alss = dip->blss = 0;
99 return;
101 if (j == FILLER && !xon)
102 return;
103 if (tflg) { /* transparent mode, undiverted */
104 if (print) /* assumes that it's ok to print */
105 /* OUT "%c", j PUT; /* i.e., is ascii */
106 outascii(i);
107 return;
109 if (TROFF && ascii)
110 outascii(i);
111 else
112 ptout(i);
116 void outweird(int k) /* like ptchname() but ascii */
118 char *chn = chname(k);
120 switch (chn[0]) {
121 case MBchar:
122 OUT "%s", chn+1 PUT; /* \n not needed? */
123 break;
124 case Number:
125 OUT "\\N'%s'", chn+1 PUT;
126 break;
127 case Troffchar:
128 if (strlen(chn+1) == 2)
129 OUT "\\(%s", chn+1 PUT;
130 else
131 OUT "\\C'%s'", chn+1 PUT;
132 break;
133 default:
134 OUT " %s? ", chn PUT;
135 break;
139 void outascii(Tchar i) /* print i in best-guess ascii */
141 int j = cbits(i);
143 /* is this ever called with NROFF set? probably doesn't work at all. */
145 if (ismot(i))
146 oput(' ');
147 else if (j < ALPHABET && j >= ' ' || j == '\n' || j == '\t')
148 oput(j);
149 else if (j == DRAWFCN)
150 oputs("\\D");
151 else if (j == HYPHEN)
152 oput('-');
153 else if (j == MINUS) /* special pleading for strange encodings */
154 oputs("\\-");
155 else if (j == PRESC)
156 oputs("\\e");
157 else if (j == FILLER)
158 oputs("\\&");
159 else if (j == UNPAD)
160 oputs("\\ ");
161 else if (j == OHC) /* this will never occur; stripped out earlier */
162 oputs("\\%");
163 else if (j == XON)
164 oputs("\\X");
165 else if (j == XOFF)
166 oputs(" ");
167 else if (j == LIG_FI)
168 oputs("fi");
169 else if (j == LIG_FL)
170 oputs("fl");
171 else if (j == LIG_FF)
172 oputs("ff");
173 else if (j == LIG_FFI)
174 oputs("ffi");
175 else if (j == LIG_FFL)
176 oputs("ffl");
177 else if (j == WORDSP) { /* nothing at all */
178 if (xon) /* except in \X */
179 oput(' ');
181 } else
182 outweird(j);
185 int flusho(void)
187 if (NROFF && !toolate && t.twinit)
188 fwrite(t.twinit, strlen(t.twinit), 1, ptid);
190 if (obufp > obuf) {
191 if (pipeflg && !toolate) {
192 /* fprintf(stderr, "Pipe to <%s>\n", Pipe.buf); */
193 if (!Pipe.buf[0] || (ptid = popen(Pipe.buf, "w")) == NULL)
194 ERROR "pipe %s not created.", Pipe.buf WARN;
195 if (Pipe.buf)
196 free(Pipe.buf);
198 if (!toolate)
199 toolate++;
200 *obufp = 0;
201 fputs(obuf, ptid);
202 fflush(ptid);
203 obufp = obuf;
205 return 1;
209 void caseex(void)
211 done(0);
215 void done(int x)
217 int i;
219 error |= x;
220 app = ds = lgf = 0;
221 if (i = em) {
222 donef = -1;
223 eschar = '\\';
224 em = 0;
225 if (control(i, 0))
226 longjmp(sjbuf, 1);
228 if (!nfo)
229 done3(0);
230 mflg = 0;
231 dip = &d[0];
232 if (woff) /* BUG!!! This isn't set anywhere */
233 wbf((Tchar)0);
234 if (pendw)
235 getword(1);
236 pendnf = 0;
237 if (donef == 1)
238 done1(0);
239 donef = 1;
240 ip = 0;
241 frame = stk;
242 nxf = frame + 1;
243 if (!ejf)
244 tbreak();
245 nflush++;
246 eject((Stack *)0);
247 longjmp(sjbuf, 1);
251 void done1(int x)
253 error |= x;
254 if (numtabp[NL].val) {
255 trap = 0;
256 eject((Stack *)0);
257 longjmp(sjbuf, 1);
259 if (!ascii)
260 pttrailer();
261 done2(0);
265 void done2(int x)
267 ptlead();
268 if (TROFF && !ascii)
269 ptstop();
270 flusho();
271 done3(x);
274 void done3(int x)
276 error |= x;
277 flusho();
278 if (NROFF)
279 twdone();
280 if (pipeflg)
281 pclose(ptid);
282 exit(error);
286 void edone(int x)
288 frame = stk;
289 nxf = frame + 1;
290 ip = 0;
291 done(x);
295 void casepi(void)
297 int j;
298 char buf[NTM];
300 if (Pipe.buf == NULL) {
301 if ((Pipe.buf = (char *)calloc(NTM, sizeof(char))) == NULL) {
302 ERROR "No buf space for pipe cmd" WARN;
303 return;
305 Pipe.tick = 1;
306 } else
307 Pipe.buf[Pipe.cnt++] = '|';
309 getline(buf, NTM);
310 j = strlen(buf);
311 if (toolate) {
312 ERROR "Cannot create pipe to %s", buf WARN;
313 return;
315 Pipe.cnt += j;
316 if (j >= NTM +1) {
317 Pipe.tick++;
318 if ((Pipe.buf = (char *)realloc(Pipe.buf, Pipe.tick * NTM * sizeof(char))) == NULL) {
319 ERROR "No more buf space for pipe cmd" WARN;
320 return;
323 strcat(Pipe.buf, buf);
324 pipeflg++;