| #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); |
| } |
| |