Blame


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