123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387 |
- #include <stdlib.h>
- #include <unistd.h>
- #include <grass/gis.h>
- #include <grass/raster.h>
- #include <grass/glocale.h>
- #include "mapcalc.h"
- #include "globals.h"
- #include "func_proto.h"
- /****************************************************************************/
- int current_depth, current_row;
- int depths, rows, columns;
- /****************************************************************************/
- static void initialize(expression *e);
- static void evaluate(expression *e);
- /****************************************************************************/
- static void allocate_buf(expression * e)
- {
- e->buf = G_malloc(columns * Rast_cell_size(e->res_type));
- }
- static void set_buf(expression * e, void *buf)
- {
- e->buf = buf;
- }
- /****************************************************************************/
- static void initialize_constant(expression * e)
- {
- allocate_buf(e);
- }
- static void initialize_variable(expression * e)
- {
- set_buf(e, e->data.var.bind->data.bind.val->buf);
- }
- static void initialize_map(expression * e)
- {
- allocate_buf(e);
- e->data.map.idx = open_map(e->data.map.name, e->data.map.mod,
- e->data.map.row, e->data.map.col);
- }
- static void initialize_function(expression * e)
- {
- int i;
- allocate_buf(e);
- e->data.func.argv = G_malloc((e->data.func.argc + 1) * sizeof(void *));
- e->data.func.argv[0] = e->buf;
- for (i = 1; i <= e->data.func.argc; i++) {
- initialize(e->data.func.args[i]);
- e->data.func.argv[i] = e->data.func.args[i]->buf;
- }
- }
- static void initialize_binding(expression * e)
- {
- initialize(e->data.bind.val);
- set_buf(e, e->data.bind.val->buf);
- }
- static void initialize(expression * e)
- {
- switch (e->type) {
- case expr_type_constant:
- initialize_constant(e);
- break;
- case expr_type_variable:
- initialize_variable(e);
- break;
- case expr_type_map:
- initialize_map(e);
- break;
- case expr_type_function:
- initialize_function(e);
- break;
- case expr_type_binding:
- initialize_binding(e);
- break;
- default:
- G_fatal_error(_("Unknown type: %d"), e->type);
- }
- }
- /****************************************************************************/
- static void do_evaluate(void *p)
- {
- evaluate((struct expression *) p);
- }
- static void begin_evaluate(struct expression *e)
- {
- G_begin_execute(do_evaluate, e, &e->worker, 0);
- }
- static void end_evaluate(struct expression *e)
- {
- G_end_execute(&e->worker);
- }
- /****************************************************************************/
- static void evaluate_constant(expression * e)
- {
- int *ibuf = e->buf;
- float *fbuf = e->buf;
- double *dbuf = e->buf;
- int i;
- switch (e->res_type) {
- case CELL_TYPE:
- for (i = 0; i < columns; i++)
- ibuf[i] = e->data.con.ival;
- break;
- case FCELL_TYPE:
- for (i = 0; i < columns; i++)
- fbuf[i] = e->data.con.fval;
- break;
- case DCELL_TYPE:
- for (i = 0; i < columns; i++)
- dbuf[i] = e->data.con.fval;
- break;
- default:
- G_fatal_error(_("Invalid type: %d"), e->res_type);
- }
- }
- static void evaluate_variable(expression * e)
- {
- /* this is a no-op */
- }
- static void evaluate_map(expression * e)
- {
- get_map_row(e->data.map.idx,
- e->data.map.mod,
- current_depth + e->data.map.depth,
- current_row + e->data.map.row,
- e->data.map.col, e->buf, e->res_type);
- }
- static void evaluate_function(expression * e)
- {
- int i;
- int res;
- if (e->data.func.argc > 1 && e->data.func.func != f_eval) {
- for (i = 1; i <= e->data.func.argc; i++)
- begin_evaluate(e->data.func.args[i]);
- for (i = 1; i <= e->data.func.argc; i++)
- end_evaluate(e->data.func.args[i]);
- }
- else
- for (i = 1; i <= e->data.func.argc; i++)
- evaluate(e->data.func.args[i]);
- res = (*e->data.func.func) (e->data.func.argc,
- e->data.func.argt, e->data.func.argv);
- switch (res) {
- case E_ARG_LO:
- G_fatal_error(_("Too few arguments for function '%s'"),
- e->data.func.name);
- break;
- case E_ARG_HI:
- G_fatal_error(_("Too many arguments for function '%s'"),
- e->data.func.name);
- break;
- case E_ARG_TYPE:
- G_fatal_error(_("Invalid argument type for function '%s'"),
- e->data.func.name);
- break;
- case E_RES_TYPE:
- G_fatal_error(_("Invalid return type for function '%s'"),
- e->data.func.name);
- break;
- case E_INV_TYPE:
- G_fatal_error(_("Unknown type for function '%s'"), e->data.func.name);
- break;
- case E_ARG_NUM:
- G_fatal_error(_("Number of arguments for function '%s'"),
- e->data.func.name);
- break;
- case E_WTF:
- G_fatal_error(_("Unknown error for function '%s'"),
- e->data.func.name);
- break;
- }
- }
- static void evaluate_binding(expression * e)
- {
- evaluate(e->data.bind.val);
- }
- /****************************************************************************/
- static void evaluate(expression * e)
- {
- switch (e->type) {
- case expr_type_constant:
- evaluate_constant(e);
- break;
- case expr_type_variable:
- evaluate_variable(e);
- break;
- case expr_type_map:
- evaluate_map(e);
- break;
- case expr_type_function:
- evaluate_function(e);
- break;
- case expr_type_binding:
- evaluate_binding(e);
- break;
- default:
- G_fatal_error(_("Unknown type: %d"), e->type);
- }
- }
- /****************************************************************************/
- static expr_list *exprs;
- /****************************************************************************/
- static void error_handler(void *p)
- {
- expr_list *l;
- for (l = exprs; l; l = l->next) {
- expression *e = l->exp;
- int fd = e->data.bind.fd;
- if (fd >= 0)
- unopen_output_map(fd);
- }
- }
- static void setup_rand(void)
- {
- /* Read PRNG seed from environment variable if available */
- /* GRASS_RND_SEED */
- const char *random_seed = getenv("GRASS_RND_SEED");
- long seed_value;
- if (!random_seed)
- return;
- seed_value = atol(random_seed);
- G_debug(3, "Read random seed from environment: %ld", seed_value);
- #if defined(HAVE_DRAND48)
- srand48(seed_value);
- #else
- srand((unsigned int)seed_value);
- #endif
- }
- void execute(expr_list * ee)
- {
- int verbose = isatty(2);
- expr_list *l;
- int count, n;
- setup_region();
- setup_rand();
- exprs = ee;
- G_add_error_handler(error_handler, NULL);
- for (l = ee; l; l = l->next) {
- expression *e = l->exp;
- const char *var;
- if (e->type != expr_type_binding && e->type != expr_type_function)
- G_fatal_error("internal error: execute: invalid type: %d",
- e->type);
- if (e->type != expr_type_binding)
- continue;
- var = e->data.bind.var;
- if (!overwrite_flag && check_output_map(var))
- G_fatal_error(_("output map <%s> exists"), var);
- }
- for (l = ee; l; l = l->next) {
- expression *e = l->exp;
- const char *var;
- expression *val;
- initialize(e);
- if (e->type != expr_type_binding)
- continue;
- var = e->data.bind.var;
- val = e->data.bind.val;
- e->data.bind.fd = open_output_map(var, val->res_type);
- }
- setup_maps();
- count = rows * depths;
- n = 0;
- G_init_workers();
- for (current_depth = 0; current_depth < depths; current_depth++)
- for (current_row = 0; current_row < rows; current_row++) {
- if (verbose)
- G_percent(n, count, 2);
- for (l = ee; l; l = l->next) {
- expression *e = l->exp;
- int fd;
- evaluate(e);
- if (e->type != expr_type_binding)
- continue;
- fd = e->data.bind.fd;
- put_map_row(fd, e->buf, e->res_type);
- }
- n++;
- }
- G_finish_workers();
- if (verbose)
- G_percent(n, count, 2);
- for (l = ee; l; l = l->next) {
- expression *e = l->exp;
- const char *var;
- expression *val;
- int fd;
- if (e->type != expr_type_binding)
- continue;
- var = e->data.bind.var;
- val = e->data.bind.val;
- fd = e->data.bind.fd;
- close_output_map(fd);
- e->data.bind.fd = -1;
- if (val->type == expr_type_map) {
- if (val->data.map.mod == 'M') {
- copy_cats(var, val->data.map.idx);
- copy_colors(var, val->data.map.idx);
- }
- copy_history(var, val->data.map.idx);
- }
- else
- create_history(var, val);
- }
- G_unset_error_routine();
- }
- /****************************************************************************/
|