]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/htmlroff/t16.c
ndb/dns: remove single-ip-address assuptions
[plan9front.git] / sys / src / cmd / htmlroff / t16.c
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 }