Blob


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