diff options
author | rsc <devnull@localhost> | 2006-02-21 18:37:05 +0000 |
---|---|---|
committer | rsc <devnull@localhost> | 2006-02-21 18:37:05 +0000 |
commit | c42a1d3d6168df56f966ea1f3ba3ef39ebbff4e4 (patch) | |
tree | 400f263e56681842ba1e6e1fdd8be453856474ef /src/cmd/htmlroff/t16.c | |
parent | 49a1496cbbb871bc623cfd0925566628e246c9ba (diff) | |
download | plan9port-c42a1d3d6168df56f966ea1f3ba3ef39ebbff4e4.tar.gz plan9port-c42a1d3d6168df56f966ea1f3ba3ef39ebbff4e4.tar.bz2 plan9port-c42a1d3d6168df56f966ea1f3ba3ef39ebbff4e4.zip |
add
Diffstat (limited to 'src/cmd/htmlroff/t16.c')
-rw-r--r-- | src/cmd/htmlroff/t16.c | 156 |
1 files changed, 156 insertions, 0 deletions
diff --git a/src/cmd/htmlroff/t16.c b/src/cmd/htmlroff/t16.c new file mode 100644 index 00000000..3a9c427e --- /dev/null +++ b/src/cmd/htmlroff/t16.c @@ -0,0 +1,156 @@ +#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); +} |