n2.c - 9base - revived minimalist port of Plan 9 userland to Unix
 (HTM) git clone git://git.suckless.org/9base
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
       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 }