t1.c 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. #include "a.h"
  2. /*
  3. * Section 1 - General Explanation.
  4. */
  5. /* 1.3 - Numerical parameter input. */
  6. char *units = "icPmnpuvx";
  7. int
  8. scale2units(char c)
  9. {
  10. int x;
  11. switch(c){
  12. case 'i': /* inch */
  13. return UPI;
  14. case 'c': /* centimeter */
  15. return 0.3937008 * UPI;
  16. case 'P': /* pica = 1/6 inch */
  17. return UPI / 6;
  18. case 'm': /* em = S points */
  19. return UPI / 72.0 * getnr(L(".s"));
  20. case 'n': /* en = em/2 */
  21. return UPI / 72.0 * getnr(L(".s")) / 2;
  22. case 'p': /* point = 1/72 inch */
  23. return UPI / 72;
  24. case 'u': /* basic unit */
  25. return 1;
  26. case 'v': /* vertical line space V */
  27. x = getnr(L(".v"));
  28. if(x == 0)
  29. x = 12 * UPI / 72;
  30. return x;
  31. case 'x': /* pixel (htmlroff addition) */
  32. return UPX;
  33. default:
  34. return 1;
  35. }
  36. }
  37. /* 1.4 - Numerical expressions. */
  38. int eval0(Rune**, int, int);
  39. int
  40. eval(Rune *s)
  41. {
  42. return eval0(&s, 1, 1);
  43. }
  44. long
  45. runestrtol(Rune *a, Rune **p)
  46. {
  47. long n;
  48. n = 0;
  49. while('0' <= *a && *a <= '9'){
  50. n = n*10 + *a-'0';
  51. a++;
  52. }
  53. *p = a;
  54. return n;
  55. }
  56. int
  57. evalscale(Rune *s, int c)
  58. {
  59. return eval0(&s, scale2units(c), 1);
  60. }
  61. int
  62. eval0(Rune **pline, int scale, int recur)
  63. {
  64. Rune *p;
  65. int neg;
  66. double f, p10;
  67. int x, y;
  68. neg = 0;
  69. p = *pline;
  70. while(*p == '-'){
  71. neg = 1 - neg;
  72. p++;
  73. }
  74. if(*p == '('){
  75. p++;
  76. x = eval0(&p, scale, 1);
  77. if (*p != ')'){
  78. *pline = p;
  79. return x;
  80. }
  81. p++;
  82. }else{
  83. f = runestrtol(p, &p);
  84. if(*p == '.'){
  85. p10 = 1.0;
  86. p++;
  87. while('0' <= *p && *p <= '9'){
  88. p10 /= 10;
  89. f += p10*(*p++ - '0');
  90. }
  91. }
  92. if(*p && strchr(units, *p)){
  93. if(scale)
  94. f *= scale2units(*p);
  95. p++;
  96. }else if(scale)
  97. f *= scale;
  98. x = f;
  99. }
  100. if(neg)
  101. x = -x;
  102. if(!recur){
  103. *pline = p;
  104. return x;
  105. }
  106. while(*p){
  107. switch(*p++) {
  108. case '+':
  109. x += eval0(&p, scale, 0);
  110. continue;
  111. case '-':
  112. x -= eval0(&p, scale, 0);
  113. continue;
  114. case '*':
  115. x *= eval0(&p, scale, 0);
  116. continue;
  117. case '/':
  118. y = eval0(&p, scale, 0);
  119. if (y == 0) {
  120. fprint(2, "%L: divide by zero %S\n", p);
  121. y = 1;
  122. }
  123. x /= y;
  124. continue;
  125. case '%':
  126. y = eval0(&p, scale, 0);
  127. if (!y) {
  128. fprint(2, "%L: modulo by zero %S\n", p);
  129. y = 1;
  130. }
  131. x %= y;
  132. continue;
  133. case '<':
  134. if (*p == '=') {
  135. p++;
  136. x = x <= eval0(&p, scale, 0);
  137. continue;
  138. }
  139. x = x < eval0(&p, scale, 0);
  140. continue;
  141. case '>':
  142. if (*p == '=') {
  143. p++;
  144. x = x >= eval0(&p, scale, 0);
  145. continue;
  146. }
  147. x = x > eval0(&p, scale, 0);
  148. continue;
  149. case '=':
  150. if (*p == '=')
  151. p++;
  152. x = x == eval0(&p, scale, 0);
  153. continue;
  154. case '&':
  155. x &= eval0(&p, scale, 0);
  156. continue;
  157. case ':':
  158. x |= eval0(&p, scale, 0);
  159. continue;
  160. }
  161. }
  162. *pline = p;
  163. return x;
  164. }
  165. void
  166. t1init(void)
  167. {
  168. Tm tm;
  169. tm = *localtime(time(0));
  170. nr(L("dw"), tm.wday+1);
  171. nr(L("dy"), tm.mday);
  172. nr(L("mo"), tm.mon);
  173. nr(L("yr"), tm.year%100);
  174. }