187 lines
2.8 KiB
C
187 lines
2.8 KiB
C
#include "a.h"
|
|
|
|
/*
|
|
* Section 1 - General Explanation.
|
|
*/
|
|
|
|
/* 1.3 - Numerical parameter input. */
|
|
char *units = "icPmnpuvx";
|
|
int
|
|
scale2units(char c)
|
|
{
|
|
int x;
|
|
|
|
switch(c){
|
|
case 'i': /* inch */
|
|
return UPI;
|
|
case 'c': /* centimeter */
|
|
return 0.3937008 * UPI;
|
|
case 'P': /* pica = 1/6 inch */
|
|
return UPI / 6;
|
|
case 'm': /* em = S points */
|
|
return UPI / 72.0 * getnr(L(".s"));
|
|
case 'n': /* en = em/2 */
|
|
return UPI / 72.0 * getnr(L(".s")) / 2;
|
|
case 'p': /* point = 1/72 inch */
|
|
return UPI / 72;
|
|
case 'u': /* basic unit */
|
|
return 1;
|
|
case 'v': /* vertical line space V */
|
|
x = getnr(L(".v"));
|
|
if(x == 0)
|
|
x = 12 * UPI / 72;
|
|
return x;
|
|
case 'x': /* pixel (htmlroff addition) */
|
|
return UPX;
|
|
default:
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
/* 1.4 - Numerical expressions. */
|
|
int eval0(Rune**, int, int);
|
|
int
|
|
eval(Rune *s)
|
|
{
|
|
return eval0(&s, 1, 1);
|
|
}
|
|
long
|
|
runestrtol(Rune *a, Rune **p)
|
|
{
|
|
long n;
|
|
|
|
n = 0;
|
|
while('0' <= *a && *a <= '9'){
|
|
n = n*10 + *a-'0';
|
|
a++;
|
|
}
|
|
*p = a;
|
|
return n;
|
|
}
|
|
|
|
int
|
|
evalscale(Rune *s, int c)
|
|
{
|
|
return eval0(&s, scale2units(c), 1);
|
|
}
|
|
|
|
int
|
|
eval0(Rune **pline, int scale, int recur)
|
|
{
|
|
Rune *p;
|
|
int neg;
|
|
double f, p10;
|
|
int x, y;
|
|
|
|
neg = 0;
|
|
p = *pline;
|
|
while(*p == '-'){
|
|
neg = 1 - neg;
|
|
p++;
|
|
}
|
|
if(*p == '('){
|
|
p++;
|
|
x = eval0(&p, scale, 1);
|
|
if (*p != ')'){
|
|
*pline = p;
|
|
return x;
|
|
}
|
|
p++;
|
|
}else{
|
|
f = runestrtol(p, &p);
|
|
if(*p == '.'){
|
|
p10 = 1.0;
|
|
p++;
|
|
while('0' <= *p && *p <= '9'){
|
|
p10 /= 10;
|
|
f += p10*(*p++ - '0');
|
|
}
|
|
}
|
|
if(*p && strchr(units, *p)){
|
|
if(scale)
|
|
f *= scale2units(*p);
|
|
p++;
|
|
}else if(scale)
|
|
f *= scale;
|
|
x = f;
|
|
}
|
|
if(neg)
|
|
x = -x;
|
|
if(!recur){
|
|
*pline = p;
|
|
return x;
|
|
}
|
|
|
|
while(*p){
|
|
switch(*p++) {
|
|
case '+':
|
|
x += eval0(&p, scale, 0);
|
|
continue;
|
|
case '-':
|
|
x -= eval0(&p, scale, 0);
|
|
continue;
|
|
case '*':
|
|
x *= eval0(&p, scale, 0);
|
|
continue;
|
|
case '/':
|
|
y = eval0(&p, scale, 0);
|
|
if (y == 0) {
|
|
fprint(2, "%L: divide by zero %S\n", p);
|
|
y = 1;
|
|
}
|
|
x /= y;
|
|
continue;
|
|
case '%':
|
|
y = eval0(&p, scale, 0);
|
|
if (!y) {
|
|
fprint(2, "%L: modulo by zero %S\n", p);
|
|
y = 1;
|
|
}
|
|
x %= y;
|
|
continue;
|
|
case '<':
|
|
if (*p == '=') {
|
|
p++;
|
|
x = x <= eval0(&p, scale, 0);
|
|
continue;
|
|
}
|
|
x = x < eval0(&p, scale, 0);
|
|
continue;
|
|
case '>':
|
|
if (*p == '=') {
|
|
p++;
|
|
x = x >= eval0(&p, scale, 0);
|
|
continue;
|
|
}
|
|
x = x > eval0(&p, scale, 0);
|
|
continue;
|
|
case '=':
|
|
if (*p == '=')
|
|
p++;
|
|
x = x == eval0(&p, scale, 0);
|
|
continue;
|
|
case '&':
|
|
x &= eval0(&p, scale, 0);
|
|
continue;
|
|
case ':':
|
|
x |= eval0(&p, scale, 0);
|
|
continue;
|
|
}
|
|
}
|
|
*pline = p;
|
|
return x;
|
|
}
|
|
|
|
void
|
|
t1init(void)
|
|
{
|
|
Tm tm;
|
|
|
|
tm = *localtime(time(0));
|
|
nr(L("dw"), tm.wday+1);
|
|
nr(L("dy"), tm.mday);
|
|
nr(L("mo"), tm.mon);
|
|
nr(L("yr"), tm.year%100);
|
|
}
|
|
|