]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/troff/n2.c
ip/ipconfig: format ipmask with %M instead of %I
[plan9front.git] / sys / src / cmd / troff / n2.c
1 /*
2  * n2.c
3  *
4  * output, cleanup
5  */
6
7 #include "tdef.h"
8 #include "fns.h"
9 #include "ext.h"
10 #include <setjmp.h>
11
12 #ifdef STRICT
13         /* not in ANSI or POSIX */
14 FILE*   popen(char*, char*);
15 #endif
16
17
18 extern  jmp_buf sjbuf;
19 int     toolate;
20 int     error;
21
22 char    obuf[2*BUFSIZ];
23 char    *obufp = obuf;
24
25         /* pipe command structure; allows redicously long commends for .pi */
26 struct Pipe {
27         char    *buf;
28         int     tick;
29         int     cnt;
30 } Pipe;
31
32
33 int     xon     = 0;    /* records if in middle of \X */
34
35 int pchar(Tchar i)
36 {
37         int j;
38         static int hx = 0;      /* records if have seen HX */
39
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 }
83
84
85 void pchar1(Tchar i)
86 {
87         int j;
88
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;
107         }
108         if (TROFF && ascii)
109                 outascii(i);
110         else
111                 ptout(i);
112 }
113
114
115 void outweird(int k)    /* like ptchname() but ascii */
116 {
117         char *chn = chname(k);
118
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;
135         }
136 }
137
138 void outascii(Tchar i)  /* print i in best-guess ascii */
139 {
140         char *p;
141         int j = cbits(i);
142
143 /* is this ever called with NROFF set? probably doesn't work at all. */
144
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(' ');
180
181         } else
182                 outweird(j);
183 }
184
185 int flusho(void)
186 {
187         if (NROFF && !toolate && t.twinit)
188                         fwrite(t.twinit, strlen(t.twinit), 1, ptid);
189
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);
197                 }
198                 if (!toolate)
199                         toolate++;
200                 *obufp = 0;
201                 fputs(obuf, ptid);
202                 fflush(ptid);
203                 obufp = obuf;
204         }
205         return 1;
206 }
207
208
209 void caseex(void)
210 {
211         done(0);
212 }
213
214
215 void done(int x) 
216 {
217         int i;
218
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);
227         }
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);
248 }
249
250
251 void done1(int x) 
252 {
253         error |= x;
254         if (numtabp[NL].val) {
255                 trap = 0;
256                 eject((Stack *)0);
257                 longjmp(sjbuf, 1);
258         }
259         if (!ascii)
260                 pttrailer();
261         done2(0);
262 }
263
264
265 void done2(int x) 
266 {
267         ptlead();
268         if (TROFF && !ascii)
269                 ptstop();
270         flusho();
271         done3(x);
272 }
273
274 void done3(int x) 
275 {
276         error |= x;
277         flusho();
278         if (NROFF)
279                 twdone();
280         if (pipeflg)
281                 pclose(ptid);
282         exit(error);
283 }
284
285
286 void edone(int x) 
287 {
288         frame = stk;
289         nxf = frame + 1;
290         ip = 0;
291         done(x);
292 }
293
294
295 void casepi(void)
296 {
297         int j;
298         char buf[NTM];
299
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;
304                 }
305                 Pipe.tick = 1;
306         } else
307                 Pipe.buf[Pipe.cnt++] = '|';
308
309         getline(buf, NTM);
310         j = strlen(buf);
311         if (toolate) {
312                 ERROR "Cannot create pipe to %s", buf WARN;
313                 return;
314         }
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;
321                 }
322         }
323         strcat(Pipe.buf, buf);
324         pipeflg++;
325 }