Blob
1 #include "a.h"3 /*4 * 16. Conditional acceptance of input.5 *6 * conditions are7 * c - condition letter (o, e, t, n)8 * !c - not c9 * N - N>010 * !N - N <= 011 * 'a'b' - if a==b12 * !'a'b' - if a!=b13 *14 * \{xxx\} can be used for newline in bodies15 *16 * .if .ie .el17 *18 */20 int iftrue[20];21 int niftrue;23 void24 startbody(void)25 {26 int c;28 while((c = getrune()) == ' ' || c == '\t')29 ;30 ungetrune(c);31 }33 void34 skipbody(void)35 {36 int c, cc, nbrace;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 }49 int50 ifeval(void)51 {52 int c, cc, neg, nc;53 Rune line[MaxLine], *p, *e, *q;54 Rune *a;56 while((c = getnext()) == ' ' || c == '\t')57 ;58 neg = 0;59 while(c == '!'){60 neg = !neg;61 c = getnext();62 }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 }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 }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 }115 void116 r_if(Rune *name)117 {118 int n;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 else129 skipbody();130 }132 void133 r_el(Rune *name)134 {135 USED(name);137 if(niftrue <= 0){138 warn("%Cel underflow", dot);139 return;140 }141 if(iftrue[--niftrue])142 skipbody();143 else144 startbody();145 }147 void148 t16init(void)149 {150 addraw(L("if"), r_if);151 addraw(L("ie"), r_if);152 addraw(L("el"), r_el);154 addesc('{', e_nop, HtmlMode|ArgMode);155 addesc('}', e_nop, HtmlMode|ArgMode);156 }