evaluate.c 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387
  1. #include <stdlib.h>
  2. #include <unistd.h>
  3. #include <grass/gis.h>
  4. #include <grass/raster.h>
  5. #include <grass/glocale.h>
  6. #include "mapcalc.h"
  7. #include "globals.h"
  8. #include "func_proto.h"
  9. /****************************************************************************/
  10. int current_depth, current_row;
  11. int depths, rows, columns;
  12. /****************************************************************************/
  13. static void initialize(expression *e);
  14. static void evaluate(expression *e);
  15. /****************************************************************************/
  16. static void allocate_buf(expression * e)
  17. {
  18. e->buf = G_malloc(columns * Rast_cell_size(e->res_type));
  19. }
  20. static void set_buf(expression * e, void *buf)
  21. {
  22. e->buf = buf;
  23. }
  24. /****************************************************************************/
  25. static void initialize_constant(expression * e)
  26. {
  27. allocate_buf(e);
  28. }
  29. static void initialize_variable(expression * e)
  30. {
  31. set_buf(e, e->data.var.bind->data.bind.val->buf);
  32. }
  33. static void initialize_map(expression * e)
  34. {
  35. allocate_buf(e);
  36. e->data.map.idx = open_map(e->data.map.name, e->data.map.mod,
  37. e->data.map.row, e->data.map.col);
  38. }
  39. static void initialize_function(expression * e)
  40. {
  41. int i;
  42. allocate_buf(e);
  43. e->data.func.argv = G_malloc((e->data.func.argc + 1) * sizeof(void *));
  44. e->data.func.argv[0] = e->buf;
  45. for (i = 1; i <= e->data.func.argc; i++) {
  46. initialize(e->data.func.args[i]);
  47. e->data.func.argv[i] = e->data.func.args[i]->buf;
  48. }
  49. }
  50. static void initialize_binding(expression * e)
  51. {
  52. initialize(e->data.bind.val);
  53. set_buf(e, e->data.bind.val->buf);
  54. }
  55. static void initialize(expression * e)
  56. {
  57. switch (e->type) {
  58. case expr_type_constant:
  59. initialize_constant(e);
  60. break;
  61. case expr_type_variable:
  62. initialize_variable(e);
  63. break;
  64. case expr_type_map:
  65. initialize_map(e);
  66. break;
  67. case expr_type_function:
  68. initialize_function(e);
  69. break;
  70. case expr_type_binding:
  71. initialize_binding(e);
  72. break;
  73. default:
  74. G_fatal_error(_("Unknown type: %d"), e->type);
  75. }
  76. }
  77. /****************************************************************************/
  78. static void do_evaluate(void *p)
  79. {
  80. evaluate((struct expression *) p);
  81. }
  82. static void begin_evaluate(struct expression *e)
  83. {
  84. G_begin_execute(do_evaluate, e, &e->worker, 0);
  85. }
  86. static void end_evaluate(struct expression *e)
  87. {
  88. G_end_execute(&e->worker);
  89. }
  90. /****************************************************************************/
  91. static void evaluate_constant(expression * e)
  92. {
  93. int *ibuf = e->buf;
  94. float *fbuf = e->buf;
  95. double *dbuf = e->buf;
  96. int i;
  97. switch (e->res_type) {
  98. case CELL_TYPE:
  99. for (i = 0; i < columns; i++)
  100. ibuf[i] = e->data.con.ival;
  101. break;
  102. case FCELL_TYPE:
  103. for (i = 0; i < columns; i++)
  104. fbuf[i] = e->data.con.fval;
  105. break;
  106. case DCELL_TYPE:
  107. for (i = 0; i < columns; i++)
  108. dbuf[i] = e->data.con.fval;
  109. break;
  110. default:
  111. G_fatal_error(_("Invalid type: %d"), e->res_type);
  112. }
  113. }
  114. static void evaluate_variable(expression * e)
  115. {
  116. /* this is a no-op */
  117. }
  118. static void evaluate_map(expression * e)
  119. {
  120. get_map_row(e->data.map.idx,
  121. e->data.map.mod,
  122. current_depth + e->data.map.depth,
  123. current_row + e->data.map.row,
  124. e->data.map.col, e->buf, e->res_type);
  125. }
  126. static void evaluate_function(expression * e)
  127. {
  128. int i;
  129. int res;
  130. if (e->data.func.argc > 1 && e->data.func.func != f_eval) {
  131. for (i = 1; i <= e->data.func.argc; i++)
  132. begin_evaluate(e->data.func.args[i]);
  133. for (i = 1; i <= e->data.func.argc; i++)
  134. end_evaluate(e->data.func.args[i]);
  135. }
  136. else
  137. for (i = 1; i <= e->data.func.argc; i++)
  138. evaluate(e->data.func.args[i]);
  139. res = (*e->data.func.func) (e->data.func.argc,
  140. e->data.func.argt, e->data.func.argv);
  141. switch (res) {
  142. case E_ARG_LO:
  143. G_fatal_error(_("Too few arguments for function '%s'"),
  144. e->data.func.name);
  145. break;
  146. case E_ARG_HI:
  147. G_fatal_error(_("Too many arguments for function '%s'"),
  148. e->data.func.name);
  149. break;
  150. case E_ARG_TYPE:
  151. G_fatal_error(_("Invalid argument type for function '%s'"),
  152. e->data.func.name);
  153. break;
  154. case E_RES_TYPE:
  155. G_fatal_error(_("Invalid return type for function '%s'"),
  156. e->data.func.name);
  157. break;
  158. case E_INV_TYPE:
  159. G_fatal_error(_("Unknown type for function '%s'"), e->data.func.name);
  160. break;
  161. case E_ARG_NUM:
  162. G_fatal_error(_("Number of arguments for function '%s'"),
  163. e->data.func.name);
  164. break;
  165. case E_WTF:
  166. G_fatal_error(_("Unknown error for function '%s'"),
  167. e->data.func.name);
  168. break;
  169. }
  170. }
  171. static void evaluate_binding(expression * e)
  172. {
  173. evaluate(e->data.bind.val);
  174. }
  175. /****************************************************************************/
  176. static void evaluate(expression * e)
  177. {
  178. switch (e->type) {
  179. case expr_type_constant:
  180. evaluate_constant(e);
  181. break;
  182. case expr_type_variable:
  183. evaluate_variable(e);
  184. break;
  185. case expr_type_map:
  186. evaluate_map(e);
  187. break;
  188. case expr_type_function:
  189. evaluate_function(e);
  190. break;
  191. case expr_type_binding:
  192. evaluate_binding(e);
  193. break;
  194. default:
  195. G_fatal_error(_("Unknown type: %d"), e->type);
  196. }
  197. }
  198. /****************************************************************************/
  199. static expr_list *exprs;
  200. /****************************************************************************/
  201. static void error_handler(void *p)
  202. {
  203. expr_list *l;
  204. for (l = exprs; l; l = l->next) {
  205. expression *e = l->exp;
  206. int fd = e->data.bind.fd;
  207. if (fd >= 0)
  208. unopen_output_map(fd);
  209. }
  210. }
  211. static void setup_rand(void)
  212. {
  213. /* Read PRNG seed from environment variable if available */
  214. /* GRASS_RND_SEED */
  215. const char *random_seed = getenv("GRASS_RND_SEED");
  216. long seed_value;
  217. if (!random_seed)
  218. return;
  219. seed_value = atol(random_seed);
  220. G_debug(3, "Read random seed from environment: %ld", seed_value);
  221. #if defined(HAVE_DRAND48)
  222. srand48(seed_value);
  223. #else
  224. srand((unsigned int)seed_value);
  225. #endif
  226. }
  227. void execute(expr_list * ee)
  228. {
  229. int verbose = isatty(2);
  230. expr_list *l;
  231. int count, n;
  232. setup_region();
  233. setup_rand();
  234. exprs = ee;
  235. G_add_error_handler(error_handler, NULL);
  236. for (l = ee; l; l = l->next) {
  237. expression *e = l->exp;
  238. const char *var;
  239. if (e->type != expr_type_binding && e->type != expr_type_function)
  240. G_fatal_error("internal error: execute: invalid type: %d",
  241. e->type);
  242. if (e->type != expr_type_binding)
  243. continue;
  244. var = e->data.bind.var;
  245. if (!overwrite_flag && check_output_map(var))
  246. G_fatal_error(_("output map <%s> exists"), var);
  247. }
  248. for (l = ee; l; l = l->next) {
  249. expression *e = l->exp;
  250. const char *var;
  251. expression *val;
  252. initialize(e);
  253. if (e->type != expr_type_binding)
  254. continue;
  255. var = e->data.bind.var;
  256. val = e->data.bind.val;
  257. e->data.bind.fd = open_output_map(var, val->res_type);
  258. }
  259. setup_maps();
  260. count = rows * depths;
  261. n = 0;
  262. G_init_workers();
  263. for (current_depth = 0; current_depth < depths; current_depth++)
  264. for (current_row = 0; current_row < rows; current_row++) {
  265. if (verbose)
  266. G_percent(n, count, 2);
  267. for (l = ee; l; l = l->next) {
  268. expression *e = l->exp;
  269. int fd;
  270. evaluate(e);
  271. if (e->type != expr_type_binding)
  272. continue;
  273. fd = e->data.bind.fd;
  274. put_map_row(fd, e->buf, e->res_type);
  275. }
  276. n++;
  277. }
  278. G_finish_workers();
  279. if (verbose)
  280. G_percent(n, count, 2);
  281. for (l = ee; l; l = l->next) {
  282. expression *e = l->exp;
  283. const char *var;
  284. expression *val;
  285. int fd;
  286. if (e->type != expr_type_binding)
  287. continue;
  288. var = e->data.bind.var;
  289. val = e->data.bind.val;
  290. fd = e->data.bind.fd;
  291. close_output_map(fd);
  292. e->data.bind.fd = -1;
  293. if (val->type == expr_type_map) {
  294. if (val->data.map.mod == 'M') {
  295. copy_cats(var, val->data.map.idx);
  296. copy_colors(var, val->data.map.idx);
  297. }
  298. copy_history(var, val->data.map.idx);
  299. }
  300. else
  301. create_history(var, val);
  302. }
  303. G_unset_error_routine();
  304. }
  305. /****************************************************************************/