URI: 
       tt16.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
       ---
       tt16.c (2261B)
       ---
            1 #include "a.h"
            2 
            3 /*
            4  * 16. Conditional acceptance of input.
            5  *
            6  *        conditions are
            7  *                c - condition letter (o, e, t, n)
            8  *                !c - not c
            9  *                N - N>0
           10  *                !N - N <= 0
           11  *                'a'b' - if a==b
           12  *                !'a'b'        - if a!=b
           13  *
           14  *        \{xxx\} can be used for newline in bodies
           15  *
           16  *        .if .ie .el
           17  *
           18  */
           19 
           20 int iftrue[20];
           21 int niftrue;
           22 
           23 void
           24 startbody(void)
           25 {
           26         int c;
           27 
           28         while((c = getrune()) == ' ' || c == '\t')
           29                 ;
           30         ungetrune(c);
           31 }
           32 
           33 void
           34 skipbody(void)
           35 {
           36         int c, cc, nbrace;
           37 
           38         nbrace = 0;
           39         for(cc=0; (c = getrune()) >= 0; cc=c){
           40                 if(c == '\n' && nbrace <= 0)
           41                         break;
           42                 if(cc == '\\' && c == '{')
           43                         nbrace++;
           44                 if(cc == '\\' && c == '}')
           45                         nbrace--;
           46         }
           47 }
           48 
           49 int
           50 ifeval(void)
           51 {
           52         int c, cc, neg, nc;
           53         Rune line[MaxLine], *p, *e, *q;
           54         Rune *a;
           55 
           56         while((c = getnext()) == ' ' || c == '\t')
           57                 ;
           58         neg = 0;
           59         while(c == '!'){
           60                 neg = !neg;
           61                 c = getnext();
           62         }
           63 
           64         if('0' <= c && c <= '9'){
           65                 ungetnext(c);
           66                 a = copyarg();
           67                 c = (eval(a)>0) ^ neg;
           68                 free(a);
           69                 return c;
           70         }
           71 
           72         switch(c){
           73         case ' ':
           74         case '\n':
           75                 ungetnext(c);
           76                 return !neg;
           77         case 'o':        /* odd page */
           78         case 't':        /* troff */
           79         case 'h':        /* htmlroff */
           80                 while((c = getrune()) != ' ' && c != '\t' && c != '\n' && c >= 0)
           81                         ;
           82                 return 1 ^ neg;
           83         case 'n':        /* nroff */
           84         case 'e':        /* even page */
           85                 while((c = getnext()) != ' ' && c != '\t' && c != '\n' && c >= 0)
           86                         ;
           87                 return 0 ^ neg;
           88         }
           89 
           90         /* string comparison 'string1'string2' */
           91         p = line;
           92         e = p+nelem(line);
           93         nc = 0;
           94         q = nil;
           95         while((cc=getnext()) >= 0 && cc != '\n' && p<e){
           96                 if(cc == c){
           97                         if(++nc == 2)
           98                                 break;
           99                         q = p;
          100                 }
          101                 *p++ = cc;
          102         }
          103         if(cc != c){
          104                 ungetnext(cc);
          105                 return 0;
          106         }
          107         if(nc < 2){
          108                 return 0;
          109         }
          110         *p = 0;
          111         return (q-line == p-(q+1)
          112                 && memcmp(line, q+1, (q-line)*sizeof(Rune))==0) ^ neg;
          113 }
          114 
          115 void
          116 r_if(Rune *name)
          117 {
          118         int n;
          119 
          120         n = ifeval();
          121         if(runestrcmp(name, L("ie")) == 0){
          122                 if(niftrue >= nelem(iftrue))
          123                         sysfatal("%Cie overflow", dot);
          124                 iftrue[niftrue++] = n;
          125         }
          126         if(n)
          127                 startbody();
          128         else
          129                 skipbody();
          130 }
          131 
          132 void
          133 r_el(Rune *name)
          134 {
          135         USED(name);
          136 
          137         if(niftrue <= 0){
          138                 warn("%Cel underflow", dot);
          139                 return;
          140         }
          141         if(iftrue[--niftrue])
          142                 skipbody();
          143         else
          144                 startbody();
          145 }
          146 
          147 void
          148 t16init(void)
          149 {
          150         addraw(L("if"), r_if);
          151         addraw(L("ie"), r_if);
          152         addraw(L("el"), r_el);
          153 
          154         addesc('{', e_nop, HtmlMode|ArgMode);
          155         addesc('}', e_nop, HtmlMode|ArgMode);
          156 }