number.c 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. #define _ISOC99_SOURCE /* to get isfinite() */
  2. #define _BSD_SOURCE /* to get __USE_MISC */
  3. #include <stdio.h>
  4. #include <string.h>
  5. #include <math.h>
  6. #include <grass/gis.h>
  7. #include <grass/glocale.h>
  8. #include "list.h"
  9. #include "mapcalc.h"
  10. typedef double (*d_func) (void);
  11. typedef double (*d_func_d) (double d);
  12. typedef double (*d_func_dd) (double d0, double d1);
  13. typedef double (*d_func_di) (double d, int i);
  14. typedef double (*d_func_dai) (double d, int *i);
  15. typedef double (*d_func_p) (void *p0);
  16. typedef double (*d_func_pp) (void *p0, void *p1);
  17. typedef double (*d_func_ppp) (void *p0, void *p1, void *p2);
  18. typedef struct Numfunc
  19. {
  20. char *name;
  21. void *func;
  22. char *proto;
  23. } NUMFUNC;
  24. /*
  25. * Prototype Types:
  26. * - all return double or casted to double
  27. * "d" (double d)
  28. * "dd" (double d, double e)
  29. * "di" (double d, int i)
  30. * "dai" (double d, int *i) [a == asterisk]
  31. *
  32. * For no argument say NULL or ""
  33. */
  34. static NUMFUNC nf[] = {
  35. {"acos", acos, "d"},
  36. {"asin", asin, "d"},
  37. {"atan", atan, "d"},
  38. {"atan2", atan2, "dd"},
  39. {"cos", cos, "d"},
  40. {"sin", sin, "d"},
  41. {"tan", tan, "d"},
  42. {"cosh", cosh, "d"},
  43. {"sinh", sinh, "d"},
  44. {"tanh", tanh, "d"},
  45. {"acosh", acosh, "d"},
  46. {"asinh", asinh, "d"},
  47. {"atanh", atanh, "d"},
  48. {"exp", exp, "d"},
  49. {"frexp", frexp, "dai"},
  50. {"ldexp", ldexp, "di"},
  51. {"ln", log, "d"},
  52. {"log10", log10, "d"},
  53. {"modf", modf, "dai"},
  54. {"pow", pow, "dd"},
  55. {"sqrt", sqrt, "d"},
  56. {"hypot", hypot, "dd"},
  57. {"cbrt", cbrt, "d"},
  58. {"ceil", ceil, "d"},
  59. {"fabs", fabs, "d"},
  60. {"floor", floor, "d"},
  61. {"fmod", fmod, "dd"},
  62. {"drem", drem, "dd"},
  63. {"j0", j0, "d"},
  64. {"j1", j1, "d"},
  65. {"jn", jn, "dd"},
  66. {"y0", y0, "d"},
  67. {"y1", y1, "d"},
  68. {"yn", yn, "dd"},
  69. {"erf", erf, "d"},
  70. {"erfc", erfc, "d"},
  71. {"lgamma", lgamma, "d"},
  72. {"rint", rint, "d"},
  73. {NULL, NULL, NULL}
  74. };
  75. void init_num(void);
  76. void shownum(double d);
  77. void setnum(SYMBOL * var, double d);
  78. SYMBOL *mknumvar(SYMBOL * var, double d);
  79. double numfunc(SYMBOL * func, SYMBOL * arglist);
  80. double numop(int op, SYMBOL * opd1, SYMBOL * opd2);
  81. SYMBOL *mknum(double d);
  82. void init_num(void)
  83. {
  84. SYMBOL *sym;
  85. int i;
  86. for (i = 0; nf[i].name; i++) {
  87. sym = putsym(nf[i].name);
  88. sym->type = sym->itype = st_nfunc;
  89. sym->v.p = nf[i].func;
  90. sym->proto = nf[i].proto;
  91. sym->rettype = st_num;
  92. }
  93. /* add some handy constants */
  94. sym = putsym("e");
  95. sym->type = sym->itype = st_num;
  96. sym->v.d = M_E;
  97. sym = putsym("pi");
  98. sym->type = sym->itype = st_num;
  99. sym->v.d = M_PI;
  100. }
  101. void shownum(double d)
  102. {
  103. if (!isfinite(d))
  104. fprintf(stdout, "\t??.??\n");
  105. else if (d == (int)d)
  106. fprintf(stdout, "\t%d\n", (int)d);
  107. else
  108. fprintf(stdout, "\t%g\n", d);
  109. }
  110. void setnum(SYMBOL * var, double d)
  111. {
  112. SYMBOL *sym;
  113. var->v.d = d;
  114. if (var->name) {
  115. sym = getsym(var->name);
  116. if (sym)
  117. sym->v.d = d;
  118. }
  119. shownum(d);
  120. freesym(var);
  121. }
  122. SYMBOL *mknumvar(SYMBOL * var, double d)
  123. {
  124. if (var) {
  125. var->name = var->v.p;
  126. var->type = var->itype = st_num;
  127. var->v.d = d;
  128. symtab = (SYMBOL *) listadd((LIST *) symtab, (LIST *) var, cmpsymsym);
  129. }
  130. else {
  131. var = (SYMBOL *) listitem(sizeof(SYMBOL));
  132. var->type = var->itype = st_num;
  133. var->v.d = d;
  134. }
  135. shownum(d);
  136. return var;
  137. }
  138. double numfunc(SYMBOL * func, SYMBOL * arglist)
  139. {
  140. double res = 0.0;
  141. int argc = -1;
  142. if (!func || !func->v.p || func->type != st_nfunc) {
  143. parseerror = 1;
  144. G_warning(_("Can't call bad num-function"));
  145. }
  146. else
  147. argc = listcnt((LIST *) arglist);
  148. if (argc == 0 && (!func->proto || !*func->proto))
  149. res = (*(d_func) func->v.p) ();
  150. else if (argc == 1 && !strcmp(func->proto, "d"))
  151. res = (*(d_func_d) func->v.p) (arglist->v.d);
  152. else if (argc == 2 && !strcmp(func->proto, "dd"))
  153. res = (*(d_func_dd) func->v.p) (arglist->v.d, arglist->next->v.d);
  154. else if (argc == 2 && !strcmp(func->proto, "di"))
  155. res = (*(d_func_di) func->v.p) (arglist->v.d,
  156. (int)arglist->next->v.d);
  157. else if (argc == 3 && !strcmp(func->proto, "dai")) {
  158. int iptr;
  159. iptr = (int)arglist->next->v.d;
  160. res = (*(d_func_dai) func->v.p) (arglist->v.d, &iptr);
  161. arglist->next->v.d = (double)iptr;
  162. }
  163. else if (argc == 1 && !strcmp(func->proto, "p"))
  164. res = (*(d_func_p) func->v.p) (arglist->v.p);
  165. else if (argc == 2 && !strcmp(func->proto, "pp"))
  166. res = (*(d_func_pp) func->v.p) (arglist->v.p, arglist->next->v.p);
  167. else if (argc == 3 && !strcmp(func->proto, "ppp"))
  168. res = (*(d_func_ppp) func->v.p) (arglist->v.p,
  169. arglist->next->v.p,
  170. arglist->next->next->v.p);
  171. else {
  172. G_warning(_("Bad arguments to numfunc %s"), func->name);
  173. parseerror = 1;
  174. }
  175. listdelall((LIST *) func, freesym);
  176. listdelall((LIST *) arglist, freesym);
  177. return res;
  178. }
  179. double numop(int op, SYMBOL * opd1, SYMBOL * opd2)
  180. {
  181. SYMBOL *func, *arglist, *f;
  182. char buf[32];
  183. double res = 0.0;
  184. if (opd1->itype == st_num)
  185. sprintf(buf, "num_op_func_%c", op);
  186. else if (opd1->itype == st_pnt)
  187. sprintf(buf, "pnt_op_func_%c", op);
  188. func = getsym(buf);
  189. if (!func) {
  190. if (opd1->itype == st_num)
  191. G_warning(_("No function defined to perform ``number %c number''"),
  192. op);
  193. else if (opd1->itype == st_pnt)
  194. G_warning(_("No function defined to perform ``point %c point''"),
  195. op);
  196. parseerror = 1;
  197. }
  198. else {
  199. f = (SYMBOL *) listitem(sizeof(SYMBOL));
  200. symcpy(f, func);
  201. f->next = NULL;
  202. func = f;
  203. arglist = (SYMBOL *) listapp(NULL, (LIST *) opd1);
  204. arglist = (SYMBOL *) listapp((LIST *) arglist, (LIST *) opd2);
  205. res = numfunc(func, arglist);
  206. }
  207. return res;
  208. }
  209. SYMBOL *mknum(double d)
  210. {
  211. SYMBOL *num;
  212. num = (SYMBOL *) listitem(sizeof(SYMBOL));
  213. num->type = num->itype = st_num;
  214. num->v.d = d;
  215. return num;
  216. }