]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/htmlroff/t1.c
ndb/dns: remove single-ip-address assuptions
[plan9front.git] / sys / src / cmd / htmlroff / t1.c
1 #include "a.h"
2  
3 /*
4  * Section 1 - General Explanation.
5  */
6
7 /* 1.3 - Numerical parameter input.  */
8 char *units = "icPmnpuvx";
9 int
10 scale2units(char c)
11 {
12         int x;
13         
14         switch(c){
15         case 'i':       /* inch */
16                 return UPI;
17         case 'c':       /* centimeter */
18                 return 0.3937008 * UPI;
19         case 'P':       /* pica = 1/6 inch */
20                 return UPI / 6;
21         case 'm':       /* em = S points */
22                 return UPI / 72.0 * getnr(L(".s"));
23         case 'n':       /* en = em/2 */
24                 return UPI / 72.0 * getnr(L(".s")) / 2;
25         case 'p':       /* point = 1/72 inch */
26                 return UPI / 72;
27         case 'u':       /* basic unit */
28                 return 1;
29         case 'v':       /* vertical line space V */
30                 x = getnr(L(".v"));
31                 if(x == 0)
32                         x = 12 * UPI / 72;
33                 return x;
34         case 'x':       /* pixel (htmlroff addition) */
35                 return UPX;
36         default:
37                 return 1;
38         }
39 }
40
41 /* 1.4 - Numerical expressions. */
42 int eval0(Rune**, int, int);
43 int
44 eval(Rune *s)
45 {
46         return eval0(&s, 1, 1);
47 }
48 long
49 runestrtol(Rune *a, Rune **p)
50 {
51         long n;
52         
53         n = 0;
54         while('0' <= *a && *a <= '9'){
55                 n = n*10 + *a-'0';
56                 a++;
57         }
58         *p = a;
59         return n;
60 }
61
62 int
63 evalscale(Rune *s, int c)
64 {
65         return eval0(&s, scale2units(c), 1);
66 }
67
68 int
69 eval0(Rune **pline, int scale, int recur)
70 {
71         Rune *p;
72         int neg;
73         double f, p10;
74         int x, y;
75
76         neg = 0;
77         p = *pline;
78         while(*p == '-'){
79                 neg = 1 - neg;
80                 p++;
81         }
82         if(*p == '('){
83                 p++;
84                 x = eval0(&p, scale, 1);
85                 if (*p != ')'){
86                         *pline = p;
87                         return x;
88                 }
89                 p++;
90         }else{
91                 f = runestrtol(p, &p);
92                 if(*p == '.'){
93                         p10 = 1.0;
94                         p++;
95                         while('0' <= *p && *p <= '9'){
96                                 p10 /= 10;
97                                 f += p10*(*p++ - '0');
98                         }
99                 }
100                 if(*p && strchr(units, *p)){
101                         if(scale)
102                                 f *= scale2units(*p);
103                         p++;
104                 }else if(scale)
105                         f *= scale;
106                 x = f;
107         }
108         if(neg)
109                 x = -x;
110         if(!recur){
111                 *pline = p;
112                 return x;
113         }
114         
115         while(*p){
116                 switch(*p++) {
117                 case '+':
118                         x += eval0(&p, scale, 0);
119                         continue;
120                 case '-':
121                         x -= eval0(&p, scale, 0);
122                         continue;
123                 case '*':
124                         x *= eval0(&p, scale, 0);
125                         continue;
126                 case '/':
127                         y = eval0(&p, scale, 0);
128                         if (y == 0) {
129                                 fprint(2, "%L: divide by zero %S\n", p);
130                                 y = 1;
131                         }
132                         x /= y;
133                         continue;
134                 case '%':
135                         y = eval0(&p, scale, 0);
136                         if (!y) {
137                                 fprint(2, "%L: modulo by zero %S\n", p);
138                                 y = 1;
139                         }
140                         x %= y;
141                         continue;
142                 case '<':
143                         if (*p == '=') {
144                                 p++;
145                                 x = x <= eval0(&p, scale, 0);
146                                 continue;
147                         }
148                         x = x < eval0(&p, scale, 0);
149                         continue;
150                 case '>':
151                         if (*p == '=') {
152                                 p++;
153                                 x = x >= eval0(&p, scale, 0);
154                                 continue;
155                         }
156                         x = x > eval0(&p, scale, 0);
157                         continue;
158                 case '=':
159                         if (*p == '=')
160                                 p++;
161                         x = x == eval0(&p, scale, 0);
162                         continue;
163                 case '&':
164                         x &= eval0(&p, scale, 0);
165                         continue;
166                 case ':':
167                         x |= eval0(&p, scale, 0);
168                         continue;
169                 }
170         }
171         *pline = p;
172         return x;
173 }
174
175 void
176 t1init(void)
177 {
178         Tm tm;
179         
180         tm = *localtime(time(0));
181         nr(L("dw"), tm.wday+1);
182         nr(L("dy"), tm.mday);
183         nr(L("mo"), tm.mon);
184         nr(L("yr"), tm.year%100);
185 }
186