Blob


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