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 }