plan9port

fork of plan9port with libvec, libstr and libsdb
Log | Files | Refs | README | LICENSE

t1.c (2810B)


      1 #include "a.h"
      2 
      3 /*
      4  * Section 1 - General Explanation.
      5  */
      6 
      7 /* 1.3 - Numerical parameter input.  */
      8 char *units = "icPmnpuvx";
      9 int
     10 scale2units(char c)
     11 {
     12 	int x;
     13 
     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 }
     40 
     41 /* 1.4 - Numerical expressions. */
     42 int eval0(Rune**, int, int);
     43 int
     44 eval(Rune *s)
     45 {
     46 	return eval0(&s, 1, 1);
     47 }
     48 long
     49 runestrtol(Rune *a, Rune **p)
     50 {
     51 	long n;
     52 
     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 }
     61 
     62 int
     63 evalscale(Rune *s, int c)
     64 {
     65 	return eval0(&s, scale2units(c), 1);
     66 }
     67 
     68 int
     69 eval0(Rune **pline, int scale, int recur)
     70 {
     71 	Rune *p;
     72 	int neg;
     73 	double f, p10;
     74 	int x, y;
     75 
     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 	}
    114 
    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 }
    174 
    175 void
    176 t1init(void)
    177 {
    178 	Tm tm;
    179 
    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 }