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 int j = cbits(i); 141 142 /* is this ever called with NROFF set? probably doesn't work at all. */ 143 144 if (ismot(i)) 145 oput(' '); 146 else if (j < ALPHABET && j >= ' ' || j == '\n' || j == '\t') 147 oput(j); 148 else if (j == DRAWFCN) 149 oputs("\\D"); 150 else if (j == HYPHEN) 151 oput('-'); 152 else if (j == MINUS) /* special pleading for strange encodings */ 153 oputs("\\-"); 154 else if (j == PRESC) 155 oputs("\\e"); 156 else if (j == FILLER) 157 oputs("\\&"); 158 else if (j == UNPAD) 159 oputs("\\ "); 160 else if (j == OHC) /* this will never occur; stripped out earlier */ 161 oputs("\\%"); 162 else if (j == XON) 163 oputs("\\X"); 164 else if (j == XOFF) 165 oputs(" "); 166 else if (j == LIG_FI) 167 oputs("fi"); 168 else if (j == LIG_FL) 169 oputs("fl"); 170 else if (j == LIG_FF) 171 oputs("ff"); 172 else if (j == LIG_FFI) 173 oputs("ffi"); 174 else if (j == LIG_FFL) 175 oputs("ffl"); 176 else if (j == WORDSP) { /* nothing at all */ 177 if (xon) /* except in \X */ 178 oput(' '); 179 180 } else 181 outweird(j); 182 } 183 184 int flusho(void) 185 { 186 if (NROFF && !toolate && t.twinit) 187 fwrite(t.twinit, strlen(t.twinit), 1, ptid); 188 189 if (obufp > obuf) { 190 if (pipeflg && !toolate) { 191 /* fprintf(stderr, "Pipe to <%s>\n", Pipe.buf); */ 192 if (!Pipe.buf[0] || (ptid = popen(Pipe.buf, "w")) == NULL) 193 ERROR "pipe %s not created.", Pipe.buf WARN; 194 if (Pipe.buf) 195 free(Pipe.buf); 196 } 197 if (!toolate) 198 toolate++; 199 *obufp = 0; 200 fputs(obuf, ptid); 201 fflush(ptid); 202 obufp = obuf; 203 } 204 return 1; 205 } 206 207 208 void caseex(void) 209 { 210 done(0); 211 } 212 213 214 void done(int x) 215 { 216 int i; 217 218 error |= x; 219 app = ds = lgf = 0; 220 if (i = em) { 221 donef = -1; 222 eschar = '\\'; 223 em = 0; 224 if (control(i, 0)) 225 longjmp(sjbuf, 1); 226 } 227 if (!nfo) 228 done3(0); 229 mflg = 0; 230 dip = &d[0]; 231 if (woff) /* BUG!!! This isn't set anywhere */ 232 wbf((Tchar)0); 233 if (pendw) 234 getword(1); 235 pendnf = 0; 236 if (donef == 1) 237 done1(0); 238 donef = 1; 239 ip = 0; 240 frame = stk; 241 nxf = frame + 1; 242 if (!ejf) 243 tbreak(); 244 nflush++; 245 eject((Stack *)0); 246 longjmp(sjbuf, 1); 247 } 248 249 250 void done1(int x) 251 { 252 error |= x; 253 if (numtabp[NL].val) { 254 trap = 0; 255 eject((Stack *)0); 256 longjmp(sjbuf, 1); 257 } 258 if (!ascii) 259 pttrailer(); 260 done2(0); 261 } 262 263 264 void done2(int x) 265 { 266 ptlead(); 267 if (TROFF && !ascii) 268 ptstop(); 269 flusho(); 270 done3(x); 271 } 272 273 void done3(int x) 274 { 275 error |= x; 276 flusho(); 277 if (NROFF) 278 twdone(); 279 if (pipeflg) 280 pclose(ptid); 281 exit(error); 282 } 283 284 285 void edone(int x) 286 { 287 frame = stk; 288 nxf = frame + 1; 289 ip = 0; 290 done(x); 291 } 292 293 294 void casepi(void) 295 { 296 int j; 297 char buf[NTM]; 298 299 if (Pipe.buf == NULL) { 300 if ((Pipe.buf = (char *)calloc(NTM, sizeof(char))) == NULL) { 301 ERROR "No buf space for pipe cmd" WARN; 302 return; 303 } 304 Pipe.tick = 1; 305 } else 306 Pipe.buf[Pipe.cnt++] = '|'; 307 308 getline(buf, NTM); 309 j = strlen(buf); 310 if (toolate) { 311 ERROR "Cannot create pipe to %s", buf WARN; 312 return; 313 } 314 Pipe.cnt += j; 315 if (j >= NTM +1) { 316 Pipe.tick++; 317 if ((Pipe.buf = (char *)realloc(Pipe.buf, Pipe.tick * NTM * sizeof(char))) == NULL) { 318 ERROR "No more buf space for pipe cmd" WARN; 319 return; 320 } 321 } 322 strcat(Pipe.buf, buf); 323 pipeflg++; 324 } 325