ref: a3b95d3e567c0ef60f9f1ead26124fb706dec20d
dir: /sys/src/cmd/htmlroff/t1.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); }