n2.c (5055B)
1 /* 2 * n2.c 3 * 4 * output, cleanup 5 */ 6 7 #define _BSD_SOURCE 1 /* popen */ 8 #include "tdef.h" 9 #include "fns.h" 10 #include "ext.h" 11 #include <setjmp.h> 12 13 #ifdef STRICT 14 /* not in ANSI or POSIX */ 15 FILE* popen(char*, char*); 16 #endif 17 18 19 extern jmp_buf sjbuf; 20 int toolate; 21 int error; 22 23 char obuf[2*BUFSIZ]; 24 char *obufp = obuf; 25 26 /* pipe command structure; allows redicously long commends for .pi */ 27 struct Pipe { 28 char *buf; 29 int tick; 30 int cnt; 31 } Pipe; 32 33 34 int xon = 0; /* records if in middle of \X */ 35 36 int pchar(Tchar i) 37 { 38 int j; 39 static int hx = 0; /* records if have seen HX */ 40 41 if (hx) { 42 hx = 0; 43 j = absmot(i); 44 if (isnmot(i)) { 45 if (j > dip->blss) 46 dip->blss = j; 47 } else { 48 if (j > dip->alss) 49 dip->alss = j; 50 ralss = dip->alss; 51 } 52 return 0; 53 } 54 if (ismot(i)) { 55 pchar1(i); 56 return 0; 57 } 58 switch (j = cbits(i)) { 59 case 0: 60 case IMP: 61 case RIGHT: 62 case LEFT: 63 return 0; 64 case HX: 65 hx = 1; 66 return 0; 67 case XON: 68 xon++; 69 break; 70 case XOFF: 71 xon--; 72 break; 73 case PRESC: 74 if (!xon && !tflg && dip == &d[0]) 75 j = eschar; /* fall through */ 76 default: 77 setcbits(i, trtab[j]); 78 } 79 if (NROFF & xon) /* rob fix for man2html */ 80 return 0; 81 pchar1(i); 82 return 0; 83 } 84 85 86 void pchar1(Tchar i) 87 { 88 int j; 89 90 j = cbits(i); 91 if (dip != &d[0]) { 92 wbf(i); 93 dip->op = offset; 94 return; 95 } 96 if (!tflg && !print) { 97 if (j == '\n') 98 dip->alss = dip->blss = 0; 99 return; 100 } 101 if (j == FILLER && !xon) 102 return; 103 if (tflg) { /* transparent mode, undiverted */ 104 if (print) /* assumes that it's ok to print */ 105 /* OUT "%c", j PUT; /* i.e., is ascii */ 106 outascii(i); 107 return; 108 } 109 if (TROFF && ascii) 110 outascii(i); 111 else 112 ptout(i); 113 } 114 115 116 void outweird(int k) /* like ptchname() but ascii */ 117 { 118 char *chn = chname(k); 119 120 switch (chn[0]) { 121 case MBchar: 122 OUT "%s", chn+1 PUT; /* \n not needed? */ 123 break; 124 case Number: 125 OUT "\\N'%s'", chn+1 PUT; 126 break; 127 case Troffchar: 128 if (strlen(chn+1) == 2) 129 OUT "\\(%s", chn+1 PUT; 130 else 131 OUT "\\C'%s'", chn+1 PUT; 132 break; 133 default: 134 OUT " %s? ", chn PUT; 135 break; 136 } 137 } 138 139 void outascii(Tchar i) /* print i in best-guess ascii */ 140 { 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 }