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