URI:
       tn2.c - plan9port - [fork] Plan 9 from user space
  HTML git clone git://src.adamsgaard.dk/plan9port
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
       tn2.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 }