123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504 |
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <grass/gis.h>
- #include <grass/glocale.h>
- #include "mapcalc.h"
- #include "func_proto.h"
- /****************************************************************************/
- static expr_list *variables;
- /****************************************************************************/
- static func_desc *find_func(const char *name)
- {
- int i;
- for (i = 0; local_func_descs[i].name; i++) {
- if (strcmp(name, local_func_descs[i].name) == 0)
- return &local_func_descs[i];
- }
- for (i = 0; calc_func_descs[i].name; i++) {
- if (strcmp(name, calc_func_descs[i].name) == 0)
- return &calc_func_descs[i];
- }
- return NULL;
- }
- static expression *find_variable(const char *name)
- {
- expr_list *l;
- for (l = variables; l; l = l->next)
- if (strcmp(name, l->exp->data.bind.var) == 0)
- return l->exp;
- return NULL;
- }
- static expression *allocate(int type, int res_type)
- {
- expression *e = G_malloc(sizeof(expression));
- e->type = type;
- e->res_type = res_type;
- e->buf = NULL;
- e->worker = NULL;
- return e;
- }
- /****************************************************************************/
- static expression *to_int(expression * e1)
- {
- expression *e = allocate(expr_type_function, CELL_TYPE);
- expression **args = G_malloc(2 * sizeof(expression *));
- int *argt = G_malloc(2 * sizeof(int));
- argt[0] = CELL_TYPE;
- args[1] = e1;
- argt[1] = e1->res_type;
- e->data.func.name = "";
- e->data.func.oper = NULL;
- e->data.func.func = f_int;
- e->data.func.argc = 1;
- e->data.func.args = args;
- e->data.func.argt = argt;
- e->data.func.argv = NULL;
- return e;
- }
- static expression *to_float(expression * e1)
- {
- expression *e = allocate(expr_type_function, FCELL_TYPE);
- expression **args = G_malloc(2 * sizeof(expression *));
- int *argt = G_malloc(2 * sizeof(int));
- argt[0] = FCELL_TYPE;
- args[1] = e1;
- argt[1] = e1->res_type;
- e->data.func.name = "";
- e->data.func.oper = NULL;
- e->data.func.func = f_float;
- e->data.func.argc = 1;
- e->data.func.args = args;
- e->data.func.argt = argt;
- e->data.func.argv = NULL;
- return e;
- }
- static expression *to_double(expression * e1)
- {
- expression *e = allocate(expr_type_function, DCELL_TYPE);
- expression **args = G_malloc(2 * sizeof(expression *));
- int *argt = G_malloc(2 * sizeof(int));
- argt[0] = DCELL_TYPE;
- args[1] = e1;
- argt[1] = e1->res_type;
- e->data.func.name = "";
- e->data.func.oper = NULL;
- e->data.func.func = f_double;
- e->data.func.argc = 1;
- e->data.func.args = args;
- e->data.func.argt = argt;
- e->data.func.argv = NULL;
- return e;
- }
- /****************************************************************************/
- int is_var(const char *name)
- {
- return find_variable(name) ? 1 : 0;
- }
- /****************************************************************************/
- void define_variable(expression * e)
- {
- variables = list(e, variables);
- }
- char *composite(const char *name, const char *mapset)
- {
- char *buf = G_malloc(strlen(name) + strlen(mapset) + 2);
- strcpy(buf, name);
- strcat(buf, "@");
- strcat(buf, mapset);
- return buf;
- }
- expr_list *list(expression * exp, expr_list * next)
- {
- expr_list *l = G_malloc(sizeof(struct expr_list));
- l->exp = exp;
- l->next = next;
- return l;
- }
- int list_length(expr_list * l)
- {
- int n = 0;
- for (; l; l = l->next)
- n++;
- return n;
- }
- expr_list *singleton(expression * e1)
- {
- return list(e1, NULL);
- }
- expr_list *pair(expression * e1, expression * e2)
- {
- return list(e1, list(e2, NULL));
- }
- expr_list *triple(expression * e1, expression * e2, expression * e3)
- {
- return list(e1, list(e2, list(e3, NULL)));
- }
- expression *constant_int(int x)
- {
- expression *e = allocate(expr_type_constant, CELL_TYPE);
- e->data.con.ival = x;
- return e;
- }
- expression *constant_float(float x)
- {
- expression *e = allocate(expr_type_constant, FCELL_TYPE);
- e->data.con.fval = x;
- return e;
- }
- expression *constant_double(double x)
- {
- expression *e = allocate(expr_type_constant, DCELL_TYPE);
- e->data.con.fval = x;
- return e;
- }
- expression *variable(const char *name)
- {
- expression *var = find_variable(name);
- expression *e;
- if (!var)
- syntax_error(_("Undefined variable '%s'"), name);
- e = allocate(expr_type_variable, var ? var->res_type : CELL_TYPE);
- e->data.var.name = name;
- e->data.var.bind = var;
- return e;
- }
- expression *mapname(const char *name, int mod, int row, int col, int depth)
- {
- int res_type = map_type(name, mod);
- expression *e = allocate(expr_type_map,
- res_type >= 0 ? res_type : CELL_TYPE);
- if (res_type < 0)
- syntax_error(_("Invalid map <%s>"), name);
- e->data.map.name = name;
- e->data.map.mod = mod;
- e->data.map.row = row;
- e->data.map.col = col;
- e->data.map.depth = depth;
- return e;
- }
- expression *binding(const char *var, expression * val)
- {
- expression *e = allocate(expr_type_binding, val->res_type);
- e->data.bind.var = var;
- e->data.bind.val = val;
- e->data.bind.fd = -1;
- return e;
- }
- expression *operator(const char *name, const char *oper, int prec,
- expr_list * arglist)
- {
- func_desc *d = find_func(name);
- int argc = list_length(arglist);
- expression **args = G_malloc((argc + 1) * sizeof(expression *));
- int *argt = G_malloc((argc + 1) * sizeof(int));
- expression *e;
- expr_list *l;
- int i;
- for (l = arglist, i = 1; l; l = l->next, i++)
- args[i] = l->exp;
- for (i = 1; i <= argc; i++)
- argt[i] = args[i]->res_type;
- argt[0] = CELL_TYPE;
- switch (!d ? -1 : d->check_args(argc, argt)) {
- case -1:
- syntax_error(_("Undefined function '%s'"), name);
- break;
- case 0:
- break;
- case E_ARG_LO:
- syntax_error(_("Too few arguments (%d) to function %s()"),
- argc, name);
- break;
- case E_ARG_HI:
- syntax_error(_("Too many arguments (%d) to function %s()"),
- argc, name);
- break;
- case E_ARG_TYPE:
- syntax_error(_("Incorrect argument types to function %s()"), name);
- break;
- default:
- G_fatal_error(_("Internal error for function %s()"), name);
- break;
- }
- for (i = 1; i <= argc; i++)
- if (argt[i] != args[i]->res_type) {
- if (argt[i] == CELL_TYPE)
- args[i] = to_int(args[i]);
- if (argt[i] == FCELL_TYPE)
- args[i] = to_float(args[i]);
- if (argt[i] == DCELL_TYPE)
- args[i] = to_double(args[i]);
- }
- e = allocate(expr_type_function, argt[0]);
- e->data.func.name = name;
- e->data.func.oper = oper;
- e->data.func.prec = prec;
- e->data.func.func = d ? d->func : NULL;
- e->data.func.argc = argc;
- e->data.func.args = args;
- e->data.func.argt = argt;
- e->data.func.argv = NULL;
- return e;
- }
- expression *function(const char *name, expr_list * arglist)
- {
- return operator(name, NULL, 0, arglist);
- }
- /****************************************************************************/
- static char *format_expression_prec(const expression * e, int prec);
- /****************************************************************************/
- static char *format_constant(const expression * e)
- {
- char buff[64];
- if (e->res_type == CELL_TYPE)
- sprintf(buff, "%d", e->data.con.ival);
- else
- sprintf(buff, "%.8g", e->data.con.fval);
- return strdup(buff);
- }
- static char *format_variable(const expression * e)
- {
- return strdup(e->data.var.name);
- }
- static char *format_map(const expression * e)
- {
- char buff[1024];
- const char *mod;
- switch (e->data.map.mod) {
- case 'r':
- mod = "r#";
- break;
- case 'g':
- mod = "g#";
- break;
- case 'b':
- mod = "b#";
- break;
- case '#':
- mod = "#";
- break;
- case '@':
- mod = "@";
- break;
- case 'M':
- mod = "";
- break;
- default:
- G_warning(_("Invalid map modifier: '%c'"), e->data.map.mod);
- mod = "?";
- break;
- }
- if (e->data.map.depth)
- sprintf(buff, "%s%s[%d,%d,%d]",
- mod, e->data.map.name,
- e->data.map.row, e->data.map.col, e->data.map.depth);
- else if (e->data.map.row || e->data.map.col)
- sprintf(buff, "%s%s[%d,%d]",
- mod, e->data.map.name, e->data.map.row, e->data.map.col);
- else
- sprintf(buff, "%s%s", mod, e->data.map.name);
- return strdup(buff);
- }
- static char *format_function(const expression * e, int prec)
- {
- char **args = NULL;
- int num_args = 0;
- char *result;
- int len;
- int i;
- if (e->data.func.argc == 1 && !*e->data.func.name)
- return format_expression_prec(e->data.func.args[1], prec);
- len = strlen(e->data.func.name) + 3;
- for (i = 1; i <= e->data.func.argc; i++) {
- if (i >= num_args) {
- num_args = i + 1000;
- args = G_realloc(args, num_args * sizeof(char *));
- }
- args[i] = format_expression_prec(e->data.func.args[i], 9);
- if (i > 1)
- len += 2;
- len += strlen(args[i]);
- }
- result = G_malloc(len);
- strcpy(result, e->data.func.name);
- strcat(result, "(");
- for (i = 1; i <= e->data.func.argc; i++) {
- if (i > 1)
- strcat(result, ", ");
- strcat(result, args[i]);
- G_free(args[i]);
- }
- strcat(result, ")");
- return result;
- }
- static char *format_operator(const expression * e, int prec)
- {
- int prec2 = e->data.func.prec;
- char *arg1, *arg2, *arg3;
- char *result;
- switch (e->data.func.argc) {
- case 1:
- arg1 = format_expression_prec(e->data.func.args[1], prec2);
- result = G_malloc(strlen(e->data.func.oper) + strlen(arg1) + 3);
- sprintf(result, "%s%s%s%s",
- prec <= prec2 ? "(" : "",
- e->data.func.oper, arg1, prec <= prec2 ? ")" : "");
- G_free(arg1);
- return result;
- case 2:
- arg1 = format_expression_prec(e->data.func.args[1], (prec2 + 1));
- arg2 = format_expression_prec(e->data.func.args[2], prec2);
- result =
- G_malloc(strlen(e->data.func.oper) + strlen(arg1) + strlen(arg2) +
- 5);
- sprintf(result, "%s%s %s %s%s", prec <= prec2 ? "(" : "", arg1,
- e->data.func.oper, arg2, prec <= prec2 ? ")" : "");
- G_free(arg1);
- G_free(arg2);
- return result;
- case 3:
- arg1 = format_expression_prec(e->data.func.args[1], prec2);
- arg2 = format_expression_prec(e->data.func.args[2], prec2);
- arg3 = format_expression_prec(e->data.func.args[3], (prec2 + 1));
- result = G_malloc(strlen(arg1) + strlen(arg2) + strlen(arg3) + 9);
- sprintf(result, "%s%s ? %s : %s%s",
- prec <= prec2 ? "(" : "",
- arg1, arg2, arg3, prec <= prec2 ? ")" : "");
- G_free(arg1);
- G_free(arg2);
- G_free(arg3);
- return result;
- default:
- G_warning(_("Illegal number of arguments (%d) for operator '%s'"),
- e->data.func.argc, e->data.func.oper);
- return format_function(e, prec);
- }
- }
- static char *format_func_op(const expression * e, int prec)
- {
- return (e->data.func.oper ? format_operator : format_function) (e, prec);
- }
- static char *format_binding(const expression * e, int prec)
- {
- char *result;
- char *expr = format_expression_prec(e->data.bind.val, 8);
- result = G_malloc(strlen(e->data.bind.var) + strlen(expr) + 6);
- sprintf(result, "%s%s = %s%s",
- prec < 8 ? "(" : "", e->data.bind.var, expr, prec < 8 ? ")" : "");
- G_free(expr);
- return result;
- }
- static char *format_expression_prec(const expression * e, int prec)
- {
- switch (e->type) {
- case expr_type_constant:
- return format_constant(e);
- case expr_type_variable:
- return format_variable(e);
- case expr_type_map:
- return format_map(e);
- case expr_type_function:
- return format_func_op(e, prec);
- case expr_type_binding:
- return format_binding(e, prec);
- default:
- G_warning(_("Format_expression_prec: unknown type: %d"), e->type);
- return strdup("??");
- }
- }
- char *format_expression(const expression * e)
- {
- return format_expression_prec(e, 9);
- }
- /****************************************************************************/
|