ref: c00c60d327168c25e56077c8310cf2380833e9be
dir: /sys/src/cmd/htmlroff/t16.c/
#include "a.h" /* * 16. Conditional acceptance of input. * * conditions are * c - condition letter (o, e, t, n) * !c - not c * N - N>0 * !N - N <= 0 * 'a'b' - if a==b * !'a'b' - if a!=b * * \{xxx\} can be used for newline in bodies * * .if .ie .el * */ int iftrue[20]; int niftrue; void startbody(void) { int c; while((c = getrune()) == ' ' || c == '\t') ; ungetrune(c); } void skipbody(void) { int c, cc, nbrace; nbrace = 0; for(cc=0; (c = getrune()) >= 0; cc=c){ if(c == '\n' && nbrace <= 0) break; if(cc == '\\' && c == '{') nbrace++; if(cc == '\\' && c == '}') nbrace--; } } int ifeval(void) { int c, cc, neg, nc; Rune line[MaxLine], *p, *e, *q; Rune *a; while((c = getnext()) == ' ' || c == '\t') ; neg = 0; while(c == '!'){ neg = !neg; c = getnext(); } if('0' <= c && c <= '9'){ ungetnext(c); a = copyarg(); c = (eval(a)>0) ^ neg; free(a); return c; } switch(c){ case ' ': case '\n': ungetnext(c); return !neg; case 'o': /* odd page */ case 't': /* troff */ case 'h': /* htmlroff */ while((c = getrune()) != ' ' && c != '\t' && c != '\n' && c >= 0) ; return 1 ^ neg; case 'n': /* nroff */ case 'e': /* even page */ while((c = getnext()) != ' ' && c != '\t' && c != '\n' && c >= 0) ; return 0 ^ neg; } /* string comparison 'string1'string2' */ p = line; e = p+nelem(line); nc = 0; q = nil; while((cc=getnext()) >= 0 && cc != '\n' && p<e){ if(cc == c){ if(++nc == 2) break; q = p; } *p++ = cc; } if(cc != c){ ungetnext(cc); return 0; } if(nc < 2){ return 0; } *p = 0; return (q-line == p-(q+1) && memcmp(line, q+1, (q-line)*sizeof(Rune))==0) ^ neg; } void r_if(Rune *name) { int n; n = ifeval(); if(runestrcmp(name, L("ie")) == 0){ if(niftrue >= nelem(iftrue)) sysfatal("%Cie overflow", dot); iftrue[niftrue++] = n; } if(n) startbody(); else skipbody(); } void r_el(Rune *name) { USED(name); if(niftrue <= 0){ warn("%Cel underflow", dot); return; } if(iftrue[--niftrue]) skipbody(); else startbody(); } void t16init(void) { addraw(L("if"), r_if); addraw(L("ie"), r_if); addraw(L("el"), r_el); addesc('{', e_nop, HtmlMode|ArgMode); addesc('}', e_nop, HtmlMode|ArgMode); }