Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 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