Blob
1 #include "a.h"3 /*4 * Section 1 - General Explanation.5 */7 /* 1.3 - Numerical parameter input. */8 char *units = "icPmnpuvx";9 int10 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 int44 eval(Rune *s)45 {46 return eval0(&s, 1, 1);47 }48 long49 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 int63 evalscale(Rune *s, int c)64 {65 return eval0(&s, scale2units(c), 1);66 }68 int69 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;107 }108 if(neg)109 x = -x;110 if(!recur){111 *pline = p;112 return x;113 }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 }175 void176 t1init(void)177 {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);185 }