Blob
1 /*2 * n2.c3 *4 * output, cleanup5 */7 #define _BSD_SOURCE 1 /* popen */8 #define _DEFAULT_SOURCE 19 #include "tdef.h"10 #include "fns.h"11 #include "ext.h"12 #include <setjmp.h>14 #ifdef STRICT15 /* not in ANSI or POSIX */16 FILE* popen(char*, char*);17 #endif20 extern jmp_buf sjbuf;21 int toolate;22 int error;24 char obuf[2*BUFSIZ];25 char *obufp = obuf;27 /* pipe command structure; allows redicously long commends for .pi */28 struct Pipe {29 char *buf;30 int tick;31 int cnt;32 } Pipe;35 int xon = 0; /* records if in middle of \X */37 int pchar(Tchar i)38 {39 int j;40 static int hx = 0; /* records if have seen HX */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 }87 void pchar1(Tchar i)88 {89 int j;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 else113 ptout(i);114 }117 void outweird(int k) /* like ptchname() but ascii */118 {119 char *chn = chname(k);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 else132 OUT "\\C'%s'", chn+1 PUT;133 break;134 default:135 OUT " %s? ", chn PUT;136 break;137 }138 }140 void outascii(Tchar i) /* print i in best-guess ascii */141 {142 int j = cbits(i);144 /* is this ever called with NROFF set? probably doesn't work at all. */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(' ');182 } else183 outweird(j);184 }186 int flusho(void)187 {188 if (NROFF && !toolate && t.twinit)189 fwrite(t.twinit, strlen(t.twinit), 1, ptid);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 }210 void caseex(void)211 {212 done(0);213 }216 void done(int x)217 {218 int i;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 }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 }266 void done2(int x)267 {268 ptlead();269 if (TROFF && !ascii)270 ptstop();271 flusho();272 done3(x);273 }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 }287 void edone(int x)288 {289 frame = stk;290 nxf = frame + 1;291 ip = 0;292 done(x);293 }296 void casepi(void)297 {298 int j;299 char buf[NTM];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 } else308 Pipe.buf[Pipe.cnt++] = '|';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 }