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