Blob


1 #include "a.h"
3 /*
4 * Section 1 - General Explanation.
5 */
7 /* 1.3 - Numerical parameter input. */
8 char *units = "icPmnpuvx";
9 int
10 scale2units(char c)
11 {
12 int x;
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 }
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;
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 }
62 int
63 evalscale(Rune *s, int c)
64 {
65 return eval0(&s, scale2units(c), 1);
66 }
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;
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;
108 if(neg)
109 x = -x;
110 if(!recur){
111 *pline = p;
112 return x;
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;
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;
140 x %= y;
141 continue;
142 case '<':
143 if (*p == '=') {
144 p++;
145 x = x <= eval0(&p, scale, 0);
146 continue;
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;
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;
171 *pline = p;
172 return x;
175 void
176 t1init(void)
178 Tm tm;
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);