123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156 |
- #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);
- }
|