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