diff options
author | Joseph Herlant <herlantj@gmail.com> | 2018-05-25 22:06:51 -0700 |
---|---|---|
committer | Joseph Herlant <aerostitch@users.noreply.github.com> | 2018-05-25 22:17:50 -0700 |
commit | 8a76acb966f7059caf9d72c853175bd923b1e9d7 (patch) | |
tree | 1735178f7a0718831b88d2c36ea18a9955de3224 /navit/command.c | |
parent | 032f15287b472f1a4b5349533f3e5b468684b281 (diff) | |
download | navit-8a76acb966f7059caf9d72c853175bd923b1e9d7.tar.gz |
cleanup:global:Use astyle to reformat everything
Diffstat (limited to 'navit/command.c')
-rw-r--r-- | navit/command.c | 2649 |
1 files changed, 1296 insertions, 1353 deletions
diff --git a/navit/command.c b/navit/command.c index a982606fa..ce872ca7e 100644 --- a/navit/command.c +++ b/navit/command.c @@ -19,8 +19,8 @@ /* gui.fullscreen=!gui.fullscreen gui.menu() -gui.get_data() -zoom_in() +gui.get_data() +zoom_in() zoom_out() speech.active=!speech.active osd_configuration=1 @@ -32,75 +32,75 @@ osd[@type=="xxx"].active=0;osd[@type=="yyy"].active=0 * The result, or interim result, of evaluating a saved command. */ struct result { - struct attr attr; /**< The attribute. If {@code allocated} is true, it stores an object that was + struct attr attr; /**< The attribute. If {@code allocated} is true, it stores an object that was * successfully retrieved. Else it is either a placeholder or a constant value. */ - double val; - const char *var; /**< If {@code allocated} is false, the name of the object to be resolved. + double val; + const char *var; /**< If {@code allocated} is false, the name of the object to be resolved. * Else, it is the name of the object successfully retrieved and stored in * {@code attr}, or {@code NULL} if retrieval failed. * Only the first {@code varlen} characters are significant. */ - int varlen; /**< Number of significant characters in {@code var} */ - const char *attrn; /**< The name of an object that has been resolved but not yet retrieved, + int varlen; /**< Number of significant characters in {@code var} */ + const char *attrn; /**< The name of an object that has been resolved but not yet retrieved, * {@code NULL} otherwise. Only the first {@code attrnlen} characters are * significant. */ - int attrnlen; /**< Number of significant characters in {@code attrn} */ - int allocated; /**< Whether the result has been calculated */ + int attrnlen; /**< Number of significant characters in {@code attrn} */ + int allocated; /**< Whether the result has been calculated */ }; struct result_list { - struct attr **attrs; + struct attr **attrs; }; struct context { - struct attr *attr; - int error; - int skip; - const char *expr; - struct result res; + struct attr *attr; + int error; + int skip; + const char *expr; + struct result res; }; /** * Information about a callback function for a saved command. */ struct command_saved_cb { - struct callback *cb; /**< The callback function */ - struct attr attr; + struct callback *cb; /**< The callback function */ + struct attr attr; }; /** * A saved command. */ struct command_saved { - struct context ctx; - struct result res; - char *command; /**< The command string itself **/ - struct event_idle *idle_ev; /**< Event to update this command **/ - struct callback *idle_cb; - struct callback *register_cb; /**< Callback to register all the callbacks **/ - struct event_idle *register_ev; /**< Idle event to register all the callbacks **/ - struct attr context_attr; /**< The root of the object hierarchy, which will be assumed as + struct context ctx; + struct result res; + char *command; /**< The command string itself **/ + struct event_idle *idle_ev; /**< Event to update this command **/ + struct callback *idle_cb; + struct callback *register_cb; /**< Callback to register all the callbacks **/ + struct event_idle *register_ev; /**< Idle event to register all the callbacks **/ + struct attr context_attr; /**< The root of the object hierarchy, which will be assumed as * the parent of all unqualified or partially qualified object * references. **/ - int num_cbs; /**< Number of entries in {@code cbs} **/ - struct command_saved_cb *cbs; /**< List of callbacks for this saved command **/ - struct callback *cb; /**< Callback that should be called when we re-evaluate **/ - int error; - int async; + int num_cbs; /**< Number of entries in {@code cbs} **/ + struct command_saved_cb *cbs; /**< List of callbacks for this saved command **/ + struct callback *cb; /**< Callback that should be called when we re-evaluate **/ + int error; + int async; }; enum error { - no_error=0, missing_double_quote, missing_opening_parenthesis, missing_closing_parenthesis, missing_closing_brace, missing_colon, missing_semicolon, wrong_type, illegal_number_format, illegal_character, missing_closing_bracket, invalid_type, not_ready, internal, eof_reached + no_error=0, missing_double_quote, missing_opening_parenthesis, missing_closing_parenthesis, missing_closing_brace, missing_colon, missing_semicolon, wrong_type, illegal_number_format, illegal_character, missing_closing_bracket, invalid_type, not_ready, internal, eof_reached }; enum op_type { - op_type_binary, op_type_prefix, op_type_suffix + op_type_binary, op_type_prefix, op_type_suffix }; enum set_type { - set_type_symbol, set_type_string, set_type_integer, set_type_float + set_type_symbol, set_type_string, set_type_integer, set_type_float }; @@ -117,52 +117,51 @@ static struct attr ** eval_list(struct context *ctx); * calling {@code g_free()} when it is no longer needed. */ char *command_error_to_text(int err) { - switch (err) { - case no_error: - return g_strdup("no_error"); - case missing_double_quote: - return g_strdup("missing_double_quote"); - case missing_opening_parenthesis: - return g_strdup("missing_opening_parenthesis"); - case missing_closing_parenthesis: - return g_strdup("missing_closing_parenthesis"); - case missing_closing_brace: - return g_strdup("missing_closing_brace"); - case missing_colon: - return g_strdup("missing_colon"); - case missing_semicolon: - return g_strdup("missing_semicolon"); - case wrong_type: - return g_strdup("wrong_type"); - case illegal_number_format: - return g_strdup("illegal_number_format"); - case illegal_character: - return g_strdup("illegal_character"); - case missing_closing_bracket: - return g_strdup("missing_closing_bracket"); - case invalid_type: - return g_strdup("invalid_type"); - case not_ready: - return g_strdup("not_ready"); - case internal: - return g_strdup("internal"); - case eof_reached: - return g_strdup("eof_reached"); - default: - return g_strdup("unknown"); - } + switch (err) { + case no_error: + return g_strdup("no_error"); + case missing_double_quote: + return g_strdup("missing_double_quote"); + case missing_opening_parenthesis: + return g_strdup("missing_opening_parenthesis"); + case missing_closing_parenthesis: + return g_strdup("missing_closing_parenthesis"); + case missing_closing_brace: + return g_strdup("missing_closing_brace"); + case missing_colon: + return g_strdup("missing_colon"); + case missing_semicolon: + return g_strdup("missing_semicolon"); + case wrong_type: + return g_strdup("wrong_type"); + case illegal_number_format: + return g_strdup("illegal_number_format"); + case illegal_character: + return g_strdup("illegal_character"); + case missing_closing_bracket: + return g_strdup("missing_closing_bracket"); + case invalid_type: + return g_strdup("invalid_type"); + case not_ready: + return g_strdup("not_ready"); + case internal: + return g_strdup("internal"); + case eof_reached: + return g_strdup("eof_reached"); + default: + return g_strdup("unknown"); + } } static void -result_free(struct result *res) -{ - if(res->allocated) { - attr_free_content(&res->attr); - res->allocated=0; - } else { - res->attr.type=type_none; - res->attr.u.data=NULL; - } +result_free(struct result *res) { + if(res->allocated) { + attr_free_content(&res->attr); + res->allocated=0; + } else { + res->attr.type=type_none; + res->attr.u.data=NULL; + } } @@ -170,27 +169,26 @@ result_free(struct result *res) static int command_register_callbacks(struct command_saved *cs); static const char * -get_op(struct context *ctx, int test, ...) -{ - char *op; - const char *ret=NULL; - va_list ap; - - while (*ctx->expr && g_ascii_isspace(*ctx->expr)) { - ctx->expr++; - } - - va_start(ap, test); - while ((op = va_arg(ap, char *))) { - if (!strncmp(ctx->expr, op, strlen(op))) { - ret=op; - if (! test) - ctx->expr+=strlen(op); - break; - } - } - va_end(ap); - return ret; +get_op(struct context *ctx, int test, ...) { + char *op; + const char *ret=NULL; + va_list ap; + + while (*ctx->expr && g_ascii_isspace(*ctx->expr)) { + ctx->expr++; + } + + va_start(ap, test); + while ((op = va_arg(ap, char *))) { + if (!strncmp(ctx->expr, op, strlen(op))) { + ret=op; + if (! test) + ctx->expr+=strlen(op); + break; + } + } + va_end(ap); + return ret; } /*static int @@ -200,36 +198,33 @@ is_int(struct result *res) }*/ static int -is_double(struct result *res) -{ - return 0; +is_double(struct result *res) { + return 0; } static void -dump(struct result *res) -{ +dump(struct result *res) { #if 0 - char object[res->varlen+1]; - char attribute[res->attrnlen+1]; - if (res->var) - strncpy(object, res->var, res->varlen); - object[res->varlen]='\0'; - if (res->attrn) - strncpy(attribute, res->attrn, res->attrnlen); - attribute[res->attrnlen]='\0'; - dbg(lvl_debug,"type:%s", attr_to_name(res->attr.type)); - dbg(lvl_debug,"attribute '%s' from '%s'", attribute, object); + char object[res->varlen+1]; + char attribute[res->attrnlen+1]; + if (res->var) + strncpy(object, res->var, res->varlen); + object[res->varlen]='\0'; + if (res->attrn) + strncpy(attribute, res->attrn, res->attrnlen); + attribute[res->attrnlen]='\0'; + dbg(lvl_debug,"type:%s", attr_to_name(res->attr.type)); + dbg(lvl_debug,"attribute '%s' from '%s'", attribute, object); #endif } static enum attr_type -command_attr_type(struct result *res) -{ - char *attrn=g_alloca(sizeof(char)*(res->attrnlen+1)); +command_attr_type(struct result *res) { + char *attrn=g_alloca(sizeof(char)*(res->attrnlen+1)); - strncpy(attrn, res->attrn, res->attrnlen); - attrn[res->attrnlen]='\0'; - return attr_from_name(attrn); + strncpy(attrn, res->attrn, res->attrnlen); + attrn[res->attrnlen]='\0'; + return attr_from_name(attrn); } /** @@ -248,39 +243,36 @@ command_attr_type(struct result *res) * occurred */ static int -command_object_get_attr(struct context *ctx, struct attr *object, enum attr_type attr_type, struct attr *ret) -{ - int r; - struct attr dup; - struct object_func *func=object_func_lookup(object->type); - if (!object->u.data || !func || !func->get_attr) { - dbg(lvl_warning, "cannot retrieve attributes from %s (%p), func=%p", attr_to_name(object->type), object->u.data, func) - return 0; - } - r=func->get_attr(object->u.data, attr_type, &dup, NULL); - if(r) - attr_dup_content(&dup,ret); - else - dbg(lvl_warning, "%s (%p) has no attribute %s", attr_to_name(object->type), object->u.data, attr_to_name(attr_type)) - return r; +command_object_get_attr(struct context *ctx, struct attr *object, enum attr_type attr_type, struct attr *ret) { + int r; + struct attr dup; + struct object_func *func=object_func_lookup(object->type); + if (!object->u.data || !func || !func->get_attr) { + dbg(lvl_warning, "cannot retrieve attributes from %s (%p), func=%p", attr_to_name(object->type), object->u.data, func) + return 0; + } + r=func->get_attr(object->u.data, attr_type, &dup, NULL); + if(r) + attr_dup_content(&dup,ret); + else + dbg(lvl_warning, "%s (%p) has no attribute %s", attr_to_name(object->type), object->u.data, attr_to_name(attr_type)) + return r; } static int -command_object_add_attr(struct context *ctx, struct attr *object, struct attr *attr) -{ - struct object_func *func=object_func_lookup(object->type); - if (!object->u.data || !func || !func->add_attr) - return 0; - return func->add_attr(object->u.data, attr); +command_object_add_attr(struct context *ctx, struct attr *object, struct attr *attr) { + struct object_func *func=object_func_lookup(object->type); + if (!object->u.data || !func || !func->add_attr) + return 0; + return func->add_attr(object->u.data, attr); } static int -command_object_remove_attr(struct context *ctx, struct attr *object, struct attr *attr) -{ - struct object_func *func=object_func_lookup(object->type); - if (!object->u.data || !func || !func->remove_attr) - return 0; - return func->remove_attr(object->u.data, attr); +command_object_remove_attr(struct context *ctx, struct attr *object, struct attr *attr) { + struct object_func *func=object_func_lookup(object->type); + if (!object->u.data || !func || !func->remove_attr) + return 0; + return func->remove_attr(object->u.data, attr); } @@ -306,57 +298,55 @@ command_object_remove_attr(struct context *ctx, struct attr *object, struct attr * @param res The result */ static void -command_get_attr(struct context *ctx, struct result *res) -{ - int result; - struct result tmp={{0,},}; - enum attr_type attr_type=command_attr_type(res); - enum attr_type parent_type = res->attr.type; /* for debugging only */ - if (ctx->skip) - return; - result=command_object_get_attr(ctx, &res->attr, attr_type, &tmp.attr); - result_free(res); - *res=tmp; - res->allocated=1; - if (result) { - dbg(lvl_debug, "successfully retrieved '%s' from '%s'", attr_to_name(attr_type), attr_to_name(parent_type)); - res->var=res->attrn; - res->varlen=res->attrnlen; - } else { - dbg(lvl_warning, "could not retrieve '%s' from '%s'", attr_to_name(attr_type), attr_to_name(parent_type)); - result_free(res); - res->attr.type=attr_none; - res->var=NULL; - res->varlen=0; - } - res->attrn=NULL; - res->attrnlen=0; - dump(res); +command_get_attr(struct context *ctx, struct result *res) { + int result; + struct result tmp= {{0,},}; + enum attr_type attr_type=command_attr_type(res); + enum attr_type parent_type = res->attr.type; /* for debugging only */ + if (ctx->skip) + return; + result=command_object_get_attr(ctx, &res->attr, attr_type, &tmp.attr); + result_free(res); + *res=tmp; + res->allocated=1; + if (result) { + dbg(lvl_debug, "successfully retrieved '%s' from '%s'", attr_to_name(attr_type), attr_to_name(parent_type)); + res->var=res->attrn; + res->varlen=res->attrnlen; + } else { + dbg(lvl_warning, "could not retrieve '%s' from '%s'", attr_to_name(attr_type), attr_to_name(parent_type)); + result_free(res); + res->attr.type=attr_none; + res->var=NULL; + res->varlen=0; + } + res->attrn=NULL; + res->attrnlen=0; + dump(res); } static void -command_set_attr(struct context *ctx, struct result *res, struct result *newres) -{ - enum attr_type attr_type=command_attr_type(res); - struct object_func *func=object_func_lookup(res->attr.type); - if (ctx->skip) - return; - if (!res->attr.u.data || !func || !func->set_attr) - return; - if (attr_type == attr_attr_types) { - char *attrn=g_alloca(sizeof(char)*(res->attrnlen+1)); - struct attr *tmp; - strncpy(attrn, res->attrn, res->attrnlen); - attrn[res->attrnlen]='\0'; - tmp=attr_new_from_text(attrn, newres->attr.u.str); - newres->attr.u.data=tmp->u.data; - newres->allocated=1; - g_free(tmp); - } - newres->attr.type=attr_type; - func->set_attr(res->attr.u.data, &newres->attr); - result_free(res); - *res=*newres; +command_set_attr(struct context *ctx, struct result *res, struct result *newres) { + enum attr_type attr_type=command_attr_type(res); + struct object_func *func=object_func_lookup(res->attr.type); + if (ctx->skip) + return; + if (!res->attr.u.data || !func || !func->set_attr) + return; + if (attr_type == attr_attr_types) { + char *attrn=g_alloca(sizeof(char)*(res->attrnlen+1)); + struct attr *tmp; + strncpy(attrn, res->attrn, res->attrnlen); + attrn[res->attrnlen]='\0'; + tmp=attr_new_from_text(attrn, newres->attr.u.str); + newres->attr.u.data=tmp->u.data; + newres->allocated=1; + g_free(tmp); + } + newres->attr.type=attr_type; + func->set_attr(res->attr.u.data, &newres->attr); + result_free(res); + *res=*newres; } /** @@ -374,15 +364,14 @@ command_set_attr(struct context *ctx, struct result *res, struct result *newres) * @param res The result */ static void -resolve_object(struct context *ctx, struct result *res) -{ - if (res->attr.type == attr_none && res->varlen) { - res->attr=*ctx->attr; - res->attrn=res->var; - res->attrnlen=res->varlen; - res->var=NULL; - res->varlen=0; - } +resolve_object(struct context *ctx, struct result *res) { + if (res->attr.type == attr_none && res->varlen) { + res->attr=*ctx->attr; + res->attrn=res->var; + res->attrnlen=res->varlen; + res->var=NULL; + res->varlen=0; + } } /** @@ -404,18 +393,16 @@ resolve_object(struct context *ctx, struct result *res) * @param res The result */ static void -resolve(struct context *ctx, struct result *res) -{ - resolve_object(ctx, res); - if (res->attrn) - command_get_attr(ctx, res); +resolve(struct context *ctx, struct result *res) { + resolve_object(ctx, res); + if (res->attrn) + command_get_attr(ctx, res); } static double -get_double(struct context *ctx, struct result *res) -{ - resolve(ctx, res); - return res->val; +get_double(struct context *ctx, struct result *res) { + resolve(ctx, res); + return res->val; } @@ -440,24 +427,23 @@ get_double(struct context *ctx, struct result *res) * @return The result of the expression, see description. */ static int -get_int_bool(struct context *ctx, int is_bool, struct result *res) -{ - resolve(ctx, res); - if (res->attr.type == attr_none) - return 0; - if (res->attr.type >= attr_type_int_begin && res->attr.type <= attr_type_int_end) { - return res->attr.u.num; - } - if (res->attr.type >= attr_type_double_begin && res->attr.type <= attr_type_double_end) { - return (int) (*res->attr.u.numd); - } - if (is_bool && ATTR_IS_OBJECT(res->attr.type)) - return res->attr.u.data != NULL; - if (is_bool && ATTR_IS_STRING(res->attr.type)) - return res->attr.u.data != NULL; - dbg(lvl_debug,"bool %d %s",is_bool,attr_to_name(res->attr.type)); - ctx->error=wrong_type; - return 0; +get_int_bool(struct context *ctx, int is_bool, struct result *res) { + resolve(ctx, res); + if (res->attr.type == attr_none) + return 0; + if (res->attr.type >= attr_type_int_begin && res->attr.type <= attr_type_int_end) { + return res->attr.u.num; + } + if (res->attr.type >= attr_type_double_begin && res->attr.type <= attr_type_double_end) { + return (int) (*res->attr.u.numd); + } + if (is_bool && ATTR_IS_OBJECT(res->attr.type)) + return res->attr.u.data != NULL; + if (is_bool && ATTR_IS_STRING(res->attr.type)) + return res->attr.u.data != NULL; + dbg(lvl_debug,"bool %d %s",is_bool,attr_to_name(res->attr.type)); + ctx->error=wrong_type; + return 0; } /** @@ -467,9 +453,8 @@ get_int_bool(struct context *ctx, int is_bool, struct result *res) * {@code get_int_bool(ctx, 0, res)}. See {@code get_int_bool()} for a description. */ static int -get_int(struct context *ctx, struct result *res) -{ - return get_int_bool(ctx, 0, res); +get_int(struct context *ctx, struct result *res) { + return get_int_bool(ctx, 0, res); } /** @@ -479,187 +464,181 @@ get_int(struct context *ctx, struct result *res) * {@code get_int_bool(ctx, 1, res)}. See {@code get_int_bool()} for a description. */ static int -get_bool(struct context *ctx, struct result *res) -{ - return !!get_int_bool(ctx, 1, res); +get_bool(struct context *ctx, struct result *res) { + return !!get_int_bool(ctx, 1, res); } static char * -get_string(struct context *ctx, struct result *res) -{ - resolve(ctx, res); - return attr_to_text(&res->attr, NULL, 0); +get_string(struct context *ctx, struct result *res) { + resolve(ctx, res); + return attr_to_text(&res->attr, NULL, 0); } static void -set_double(struct result *res, double val) -{ - result_free(res); - res->attr.type=attr_type_double_begin; - res->attr.u.numd=&res->val; - res->val=val; +set_double(struct result *res, double val) { + result_free(res); + res->attr.type=attr_type_double_begin; + res->attr.u.numd=&res->val; + res->val=val; } static void -set_int(struct result *res, int val) -{ - result_free(res); - res->attr.type=attr_type_int_begin; - res->attr.u.num=val; +set_int(struct result *res, int val) { + result_free(res); + res->attr.type=attr_type_int_begin; + res->attr.u.num=val; } static void -result_op(struct context *ctx, enum op_type op_type, const char *op, struct result *inout, struct result *in) -{ - if (ctx->skip) - return; - switch (op_type) { - case op_type_prefix: - switch ((op[0] << 8) | op[1]) { - case ('!' << 8): - set_int(inout, !get_bool(ctx, inout)); - return; - case ('~' << 8): - set_int(inout, ~get_int(ctx, inout)); - return; - } - break; - case op_type_binary: - resolve(ctx, inout); - resolve(ctx, in); - switch ((op[0] << 8) | op[1]) { - case ('=' << 8)|'=': - if (inout->attr.type == attr_none || in->attr.type == attr_none) { - set_int(inout, 0); - } else if (ATTR_IS_STRING(inout->attr.type) && ATTR_IS_STRING(in->attr.type)) { - char *s1=get_string(ctx, inout),*s2=get_string(ctx, in); - set_int(inout, (!strcmp(s1,s2))); - g_free(s1); - g_free(s2); - } else if (ATTR_IS_OBJECT(inout->attr.type) && ATTR_IS_OBJECT(in->attr.type)) { - set_int(inout, inout->attr.u.data == in->attr.u.data); - } else - set_int(inout, (get_int(ctx, inout) == get_int(ctx, in))); - return; - case ('!' << 8)|'=': - if (inout->attr.type == attr_none || in->attr.type == attr_none) { - set_int(inout, 1); - } else if (ATTR_IS_STRING(inout->attr.type) && ATTR_IS_STRING(in->attr.type)) { - char *s1=get_string(ctx, inout),*s2=get_string(ctx, in); - set_int(inout, (!!strcmp(s1,s2))); - g_free(s1); - g_free(s2); - } else if (ATTR_IS_OBJECT(inout->attr.type) && ATTR_IS_OBJECT(in->attr.type)) { - set_int(inout, inout->attr.u.data != in->attr.u.data); - } else - set_int(inout, (get_int(ctx, inout) != get_int(ctx, in))); - return; - case ('<' << 8): - set_int(inout, (get_int(ctx, inout) < get_int(ctx, in))); - return; - case ('<' << 8)|'=': - set_int(inout, (get_int(ctx, inout) <= get_int(ctx, in))); - return; - case ('>' << 8): - set_int(inout, (get_int(ctx, inout) > get_int(ctx, in))); - return; - case ('>' << 8)|'=': - set_int(inout, (get_int(ctx, inout) >= get_int(ctx, in))); - return; - case ('*' << 8): - if (is_double(inout) || is_double(in)) - set_double(inout, get_double(ctx, inout) * get_double(ctx, in)); - else - set_int(inout, get_int(ctx, inout) * get_int(ctx, in)); - return; - case ('/' << 8): - if (is_double(inout) || is_double(in)) - set_double(inout, get_double(ctx, inout) * get_double(ctx, in)); - else - set_int(inout, get_int(ctx, inout) * get_int(ctx, in)); - return; - case ('%' << 8): - set_int(inout, get_int(ctx, inout) % get_int(ctx, in)); - return; - case ('+' << 8): - if (is_double(inout) || is_double(in)) - set_double(inout, get_double(ctx, inout) + get_double(ctx, in)); - else if (ATTR_IS_STRING(inout->attr.type) && ATTR_IS_STRING(in->attr.type)) { - char *str=g_strdup_printf("%s%s",inout->attr.u.str,in->attr.u.str); - result_free(inout); - inout->attr.type=attr_type_string_begin; - inout->attr.u.str=str; - inout->allocated=1; - } else - set_int(inout, get_int(ctx, inout) + get_int(ctx, in)); - return; - case ('-' << 8): - if (is_double(inout) || is_double(in)) - set_int(inout, get_int(ctx, inout) - get_int(ctx, in)); - else - set_double(inout, get_double(ctx, inout) - get_double(ctx, in)); - return; - case ('&' << 8): - set_int(inout, get_int(ctx, inout) & get_int(ctx, in)); - return; - case ('^' << 8): - set_int(inout, get_int(ctx, inout) ^ get_int(ctx, in)); - return; - case ('|' << 8): - set_int(inout, get_int(ctx, inout) | get_int(ctx, in)); - return; - case (('&' << 8) | '&'): - set_int(inout, get_int(ctx, inout) && get_int(ctx, in)); - return; - case (('|' << 8) | '|'): - set_int(inout, get_int(ctx, inout) || get_int(ctx, in)); - return; - default: - break; - } - default: - break; - } - dbg(lvl_error,"Unknown op %d %s",op_type,op); - ctx->error=internal; +result_op(struct context *ctx, enum op_type op_type, const char *op, struct result *inout, struct result *in) { + if (ctx->skip) + return; + switch (op_type) { + case op_type_prefix: + switch ((op[0] << 8) | op[1]) { + case ('!' << 8): + set_int(inout, !get_bool(ctx, inout)); + return; + case ('~' << 8): + set_int(inout, ~get_int(ctx, inout)); + return; + } + break; + case op_type_binary: + resolve(ctx, inout); + resolve(ctx, in); + switch ((op[0] << 8) | op[1]) { + case ('=' << 8)|'=': + if (inout->attr.type == attr_none || in->attr.type == attr_none) { + set_int(inout, 0); + } else if (ATTR_IS_STRING(inout->attr.type) && ATTR_IS_STRING(in->attr.type)) { + char *s1=get_string(ctx, inout),*s2=get_string(ctx, in); + set_int(inout, (!strcmp(s1,s2))); + g_free(s1); + g_free(s2); + } else if (ATTR_IS_OBJECT(inout->attr.type) && ATTR_IS_OBJECT(in->attr.type)) { + set_int(inout, inout->attr.u.data == in->attr.u.data); + } else + set_int(inout, (get_int(ctx, inout) == get_int(ctx, in))); + return; + case ('!' << 8)|'=': + if (inout->attr.type == attr_none || in->attr.type == attr_none) { + set_int(inout, 1); + } else if (ATTR_IS_STRING(inout->attr.type) && ATTR_IS_STRING(in->attr.type)) { + char *s1=get_string(ctx, inout),*s2=get_string(ctx, in); + set_int(inout, (!!strcmp(s1,s2))); + g_free(s1); + g_free(s2); + } else if (ATTR_IS_OBJECT(inout->attr.type) && ATTR_IS_OBJECT(in->attr.type)) { + set_int(inout, inout->attr.u.data != in->attr.u.data); + } else + set_int(inout, (get_int(ctx, inout) != get_int(ctx, in))); + return; + case ('<' << 8): + set_int(inout, (get_int(ctx, inout) < get_int(ctx, in))); + return; + case ('<' << 8)|'=': + set_int(inout, (get_int(ctx, inout) <= get_int(ctx, in))); + return; + case ('>' << 8): + set_int(inout, (get_int(ctx, inout) > get_int(ctx, in))); + return; + case ('>' << 8)|'=': + set_int(inout, (get_int(ctx, inout) >= get_int(ctx, in))); + return; + case ('*' << 8): + if (is_double(inout) || is_double(in)) + set_double(inout, get_double(ctx, inout) * get_double(ctx, in)); + else + set_int(inout, get_int(ctx, inout) * get_int(ctx, in)); + return; + case ('/' << 8): + if (is_double(inout) || is_double(in)) + set_double(inout, get_double(ctx, inout) * get_double(ctx, in)); + else + set_int(inout, get_int(ctx, inout) * get_int(ctx, in)); + return; + case ('%' << 8): + set_int(inout, get_int(ctx, inout) % get_int(ctx, in)); + return; + case ('+' << 8): + if (is_double(inout) || is_double(in)) + set_double(inout, get_double(ctx, inout) + get_double(ctx, in)); + else if (ATTR_IS_STRING(inout->attr.type) && ATTR_IS_STRING(in->attr.type)) { + char *str=g_strdup_printf("%s%s",inout->attr.u.str,in->attr.u.str); + result_free(inout); + inout->attr.type=attr_type_string_begin; + inout->attr.u.str=str; + inout->allocated=1; + } else + set_int(inout, get_int(ctx, inout) + get_int(ctx, in)); + return; + case ('-' << 8): + if (is_double(inout) || is_double(in)) + set_int(inout, get_int(ctx, inout) - get_int(ctx, in)); + else + set_double(inout, get_double(ctx, inout) - get_double(ctx, in)); + return; + case ('&' << 8): + set_int(inout, get_int(ctx, inout) & get_int(ctx, in)); + return; + case ('^' << 8): + set_int(inout, get_int(ctx, inout) ^ get_int(ctx, in)); + return; + case ('|' << 8): + set_int(inout, get_int(ctx, inout) | get_int(ctx, in)); + return; + case (('&' << 8) | '&'): + set_int(inout, get_int(ctx, inout) && get_int(ctx, in)); + return; + case (('|' << 8) | '|'): + set_int(inout, get_int(ctx, inout) || get_int(ctx, in)); + return; + default: + break; + } + default: + break; + } + dbg(lvl_error,"Unknown op %d %s",op_type,op); + ctx->error=internal; } static void -result_set(struct context *ctx, enum set_type set_type, const char *op, int len, struct result *out) -{ - if (ctx->skip) - return; - switch (set_type) { - case set_type_symbol: - out->attr.type=attr_none; - out->var=op; - out->varlen=len; - return; - case set_type_integer: - out->attr.type=attr_type_int_begin; - out->attr.u.num=atoi(ctx->expr); - return; - case set_type_float: - out->val = strtod(ctx->expr, NULL); - out->attr.type=attr_type_double_begin; - out->attr.u.numd=&out->val; - return; - case set_type_string: - if (len >= 2) { - out->attr.type=attr_type_string_begin; - out->attr.u.str=g_malloc(len-1); - strncpy(out->attr.u.str, op+1, len-2); - out->attr.u.str[len-2]='\0'; - out->allocated=1; - return; - } - break; - default: - break; - } - dbg(lvl_error,"unknown set type %d %s",set_type,op); - ctx->error=internal; +result_set(struct context *ctx, enum set_type set_type, const char *op, int len, struct result *out) { + if (ctx->skip) + return; + switch (set_type) { + case set_type_symbol: + out->attr.type=attr_none; + out->var=op; + out->varlen=len; + return; + case set_type_integer: + out->attr.type=attr_type_int_begin; + out->attr.u.num=atoi(ctx->expr); + return; + case set_type_float: + out->val = strtod(ctx->expr, NULL); + out->attr.type=attr_type_double_begin; + out->attr.u.numd=&out->val; + return; + case set_type_string: + if (len >= 2) { + out->attr.type=attr_type_string_begin; + out->attr.u.str=g_malloc(len-1); + strncpy(out->attr.u.str, op+1, len-2); + out->attr.u.str[len-2]='\0'; + out->allocated=1; + return; + } + break; + default: + break; + } + dbg(lvl_error,"unknown set type %d %s",set_type,op); + ctx->error=internal; } /** @@ -695,94 +674,95 @@ result_set(struct context *ctx, enum set_type set_type, const char *op, int len, */ static void eval_value(struct context *ctx, struct result *res) { - const char *op; - int dots=0; - - result_free(res); - - res->varlen=0; - res->var=NULL; - res->attrnlen=0; - res->attrn=NULL; - - while (g_ascii_isspace(*(ctx->expr))) { - ctx->expr++; - } - op = ctx->expr; - - if ((op[0] >= 'a' && op[0] <= 'z') || (op[0] >= 'A' && op[0] <= 'Z') || op[0] == '_') { - const char *s=op; - for (;;) { - while ((op[0] >= 'a' && op[0] <= 'z') || (op[0] >= 'A' && op[0] <= 'Z') || (op[0] >= '0' && op[0] <= '9') || op[0] == '_') { - op++; - } - if (op-s == 3 && !strncmp(s,"new",3) && op[0] == ' ') { - op++; - } else - break; - } - result_set(ctx, set_type_symbol, ctx->expr, op-ctx->expr, res); - ctx->expr=op; - return; - } - if ((op[0] >= '0' && op[0] <= '9') || - (op[0] == '.' && op[1] >= '0' && op[1] <= '9') || - (op[0] == '-' && op[1] >= '0' && op[1] <= '9') || - (op[0] == '-' && op[1] == '.' && op[2] >= '0' && op[2] <= '9')) { - while ((op[0] >= '0' && op[0] <= '9') || op[0] == '.' || (res->varlen == 0 && op[0] == '-')) { - if (op[0] == '.') - dots++; - if (dots > 1) { - ctx->error=illegal_number_format; - return; - } - op++; - } - result_set(ctx, dots?set_type_float:set_type_integer, ctx->expr, op-ctx->expr, res); - ctx->expr=op; - return; - } - if (op[0] == '"') { - int escaped=0; - do { - if (op[0] == '\\') { - escaped=1; - if (op[1] == '"') - op++; - } - op++; - } while (op[0] && op[0] != '"'); - if(!*op) { - ctx->error=missing_double_quote; - return; - } - op++; - if (escaped) { - char *tmpstr=g_malloc(op-ctx->expr+1),*s=tmpstr; - op=ctx->expr; - do { - if (op[0] == '\\') - op++; - *s++=*op++; - } while (op[0] != '"'); - *s++=*op++; - result_set(ctx, set_type_string, tmpstr, s-tmpstr, res); - g_free(tmpstr); - } else - result_set(ctx, set_type_string, ctx->expr, op-ctx->expr, res); - ctx->expr=op; - return; - } - if (!*op) - ctx->error=eof_reached; - else { - /* - * If we get here, ctx->expr does not begin with a variable or a literal value. This is not an - * error if this function is being called to test if an expression begins with a value. - */ - dbg(lvl_debug, "character 0x%x is illegal in a value",*op); - ctx->error=illegal_character; - } + const char *op; + int dots=0; + + result_free(res); + + res->varlen=0; + res->var=NULL; + res->attrnlen=0; + res->attrn=NULL; + + while (g_ascii_isspace(*(ctx->expr))) { + ctx->expr++; + } + op = ctx->expr; + + if ((op[0] >= 'a' && op[0] <= 'z') || (op[0] >= 'A' && op[0] <= 'Z') || op[0] == '_') { + const char *s=op; + for (;;) { + while ((op[0] >= 'a' && op[0] <= 'z') || (op[0] >= 'A' && op[0] <= 'Z') || (op[0] >= '0' && op[0] <= '9') + || op[0] == '_') { + op++; + } + if (op-s == 3 && !strncmp(s,"new",3) && op[0] == ' ') { + op++; + } else + break; + } + result_set(ctx, set_type_symbol, ctx->expr, op-ctx->expr, res); + ctx->expr=op; + return; + } + if ((op[0] >= '0' && op[0] <= '9') || + (op[0] == '.' && op[1] >= '0' && op[1] <= '9') || + (op[0] == '-' && op[1] >= '0' && op[1] <= '9') || + (op[0] == '-' && op[1] == '.' && op[2] >= '0' && op[2] <= '9')) { + while ((op[0] >= '0' && op[0] <= '9') || op[0] == '.' || (res->varlen == 0 && op[0] == '-')) { + if (op[0] == '.') + dots++; + if (dots > 1) { + ctx->error=illegal_number_format; + return; + } + op++; + } + result_set(ctx, dots?set_type_float:set_type_integer, ctx->expr, op-ctx->expr, res); + ctx->expr=op; + return; + } + if (op[0] == '"') { + int escaped=0; + do { + if (op[0] == '\\') { + escaped=1; + if (op[1] == '"') + op++; + } + op++; + } while (op[0] && op[0] != '"'); + if(!*op) { + ctx->error=missing_double_quote; + return; + } + op++; + if (escaped) { + char *tmpstr=g_malloc(op-ctx->expr+1),*s=tmpstr; + op=ctx->expr; + do { + if (op[0] == '\\') + op++; + *s++=*op++; + } while (op[0] != '"'); + *s++=*op++; + result_set(ctx, set_type_string, tmpstr, s-tmpstr, res); + g_free(tmpstr); + } else + result_set(ctx, set_type_string, ctx->expr, op-ctx->expr, res); + ctx->expr=op; + return; + } + if (!*op) + ctx->error=eof_reached; + else { + /* + * If we get here, ctx->expr does not begin with a variable or a literal value. This is not an + * error if this function is being called to test if an expression begins with a value. + */ + dbg(lvl_debug, "character 0x%x is illegal in a value",*op); + ctx->error=illegal_character; + } } /** @@ -809,824 +789,795 @@ eval_value(struct context *ctx, struct result *res) { */ static int get_next_object(struct context *ctx, struct result *res) { - - while (*ctx->expr) { - res->varlen = 0; - ctx->error = 0; - - eval_value(ctx,res); - - if ((res->attr.type == attr_none) && (res->varlen > 0)) { - if (ctx->expr[0] != '.') { - return 1; // 1 means "this is the final object name" - } else { - return 2; // 2 means "there are more object names following" (e.g. we just hit 'vehicle' in 'vehicle.position_speed' - } - } - - if (ctx->error) { - // Probably hit an operator - ctx->expr++; - } - } - - return 0; + + while (*ctx->expr) { + res->varlen = 0; + ctx->error = 0; + + eval_value(ctx,res); + + if ((res->attr.type == attr_none) && (res->varlen > 0)) { + if (ctx->expr[0] != '.') { + return 1; // 1 means "this is the final object name" + } else { + return 2; // 2 means "there are more object names following" (e.g. we just hit 'vehicle' in 'vehicle.position_speed' + } + } + + if (ctx->error) { + // Probably hit an operator + ctx->expr++; + } + } + + return 0; } static void -eval_brace(struct context *ctx, struct result *res) -{ - if (get_op(ctx,0,"(",NULL)) { - eval_comma(ctx, res); - if (ctx->error) return; - if (!get_op(ctx,0,")",NULL)) - ctx->error=missing_closing_parenthesis; - return; - } - eval_value(ctx, res); +eval_brace(struct context *ctx, struct result *res) { + if (get_op(ctx,0,"(",NULL)) { + eval_comma(ctx, res); + if (ctx->error) return; + if (!get_op(ctx,0,")",NULL)) + ctx->error=missing_closing_parenthesis; + return; + } + eval_value(ctx, res); } static void -command_call_function(struct context *ctx, struct result *res) -{ - struct attr cbl,**list=NULL; - char *function=g_alloca(sizeof(char)*(res->attrnlen+1)); - if (res->attrn) - strncpy(function, res->attrn, res->attrnlen); - function[res->attrnlen]='\0'; - dbg(lvl_debug,"function=%s", function); - if (ctx->expr[0] != ')') { - list=eval_list(ctx); - if (ctx->error) { - attr_list_free(list); - return; - } - } - if (!get_op(ctx,0,")",NULL)) { - attr_list_free(list); - ctx->error=missing_closing_parenthesis; - return; - } - if (!ctx->skip) { - if (!strcmp(function,"_") && list && list[0] && list[0]->type >= attr_type_string_begin && list[0]->type <= attr_type_string_end) { - result_free(res); - res->attr.type=list[0]->type; - res->attr.u.str=g_strdup(navit_nls_gettext(list[0]->u.str)); - res->allocated=1; - - } else if (!strncmp(function,"new ",4)) { - enum attr_type attr_type=attr_from_name(function+4); - result_free(res); - if (ATTR_IS_INT(attr_type)) { - if (list && list[0] && ATTR_IS_INT(list[0]->type)) { - res->attr.type=attr_type; - res->attr.u.num=list[0]->u.num; - res->allocated=0; - } else { - dbg(lvl_error,"don't know how to create int of args"); - } - } else if (ATTR_IS_STRING(attr_type)) { - if (list && list[0] && ATTR_IS_STRING(list[0]->type)) { - res->attr.type=attr_type; - res->attr.u.str=g_strdup(list[0]->u.str); - res->allocated=1; - } else { - dbg(lvl_error,"don't know how to create string of args"); - } - } else if (ATTR_IS_OBJECT(attr_type)) { - struct object_func *func=object_func_lookup(attr_type); - if (func && func->create) { - res->attr.type=attr_type; - res->attr.u.data=func->create(list[0], list+1); - /* Setting allocated to 1 here will make object to be destroyed when last reference is destroyed. - So created persistent objects should be stored with set_attr_var command. */ - res->allocated=1; - } - } else { - dbg(lvl_error,"don't know how to create %s (%s)",attr_to_name(attr_type),function+4); - } - } else if (!strcmp(function,"add_attr")) { - command_object_add_attr(ctx, &res->attr, list[0]); - } else if (!strcmp(function,"remove_attr")) { - command_object_remove_attr(ctx, &res->attr, list[0]); - } else { - if (command_object_get_attr(ctx, &res->attr, attr_callback_list, &cbl)) { - int valid =0; - struct attr **out=NULL; - dbg(lvl_debug,"function call %s from %s",function, attr_to_name(res->attr.type)); - callback_list_call_attr_4(cbl.u.callback_list, attr_command, function, list, &out, &valid); - if (valid!=1){ - dbg(lvl_error, "invalid command ignored: \"%s\"; see http://wiki.navit-project.org/index.php/" - "OSD#Navit_commands for valid commands.", function); - } - if (out && out[0]) { - result_free(res); - attr_dup_content(out[0], &res->attr); - res->allocated=1; - attr_list_free(out); - } else - result_free(res); - } else - result_free(res); - } - } - attr_list_free(list); - res->var=NULL; - res->varlen=0; - res->attrn=NULL; - res->attrnlen=0; +command_call_function(struct context *ctx, struct result *res) { + struct attr cbl,**list=NULL; + char *function=g_alloca(sizeof(char)*(res->attrnlen+1)); + if (res->attrn) + strncpy(function, res->attrn, res->attrnlen); + function[res->attrnlen]='\0'; + dbg(lvl_debug,"function=%s", function); + if (ctx->expr[0] != ')') { + list=eval_list(ctx); + if (ctx->error) { + attr_list_free(list); + return; + } + } + if (!get_op(ctx,0,")",NULL)) { + attr_list_free(list); + ctx->error=missing_closing_parenthesis; + return; + } + if (!ctx->skip) { + if (!strcmp(function,"_") && list && list[0] && list[0]->type >= attr_type_string_begin + && list[0]->type <= attr_type_string_end) { + result_free(res); + res->attr.type=list[0]->type; + res->attr.u.str=g_strdup(navit_nls_gettext(list[0]->u.str)); + res->allocated=1; + + } else if (!strncmp(function,"new ",4)) { + enum attr_type attr_type=attr_from_name(function+4); + result_free(res); + if (ATTR_IS_INT(attr_type)) { + if (list && list[0] && ATTR_IS_INT(list[0]->type)) { + res->attr.type=attr_type; + res->attr.u.num=list[0]->u.num; + res->allocated=0; + } else { + dbg(lvl_error,"don't know how to create int of args"); + } + } else if (ATTR_IS_STRING(attr_type)) { + if (list && list[0] && ATTR_IS_STRING(list[0]->type)) { + res->attr.type=attr_type; + res->attr.u.str=g_strdup(list[0]->u.str); + res->allocated=1; + } else { + dbg(lvl_error,"don't know how to create string of args"); + } + } else if (ATTR_IS_OBJECT(attr_type)) { + struct object_func *func=object_func_lookup(attr_type); + if (func && func->create) { + res->attr.type=attr_type; + res->attr.u.data=func->create(list[0], list+1); + /* Setting allocated to 1 here will make object to be destroyed when last reference is destroyed. + So created persistent objects should be stored with set_attr_var command. */ + res->allocated=1; + } + } else { + dbg(lvl_error,"don't know how to create %s (%s)",attr_to_name(attr_type),function+4); + } + } else if (!strcmp(function,"add_attr")) { + command_object_add_attr(ctx, &res->attr, list[0]); + } else if (!strcmp(function,"remove_attr")) { + command_object_remove_attr(ctx, &res->attr, list[0]); + } else { + if (command_object_get_attr(ctx, &res->attr, attr_callback_list, &cbl)) { + int valid =0; + struct attr **out=NULL; + dbg(lvl_debug,"function call %s from %s",function, attr_to_name(res->attr.type)); + callback_list_call_attr_4(cbl.u.callback_list, attr_command, function, list, &out, &valid); + if (valid!=1) { + dbg(lvl_error, "invalid command ignored: \"%s\"; see http://wiki.navit-project.org/index.php/" + "OSD#Navit_commands for valid commands.", function); + } + if (out && out[0]) { + result_free(res); + attr_dup_content(out[0], &res->attr); + res->allocated=1; + attr_list_free(out); + } else + result_free(res); + } else + result_free(res); + } + } + attr_list_free(list); + res->var=NULL; + res->varlen=0; + res->attrn=NULL; + res->attrnlen=0; } static void -eval_postfix(struct context *ctx, struct result *res) -{ - struct result tmp={{0,},}; - const char *op; - - eval_brace(ctx, res); - if (ctx->error) return; - for (;;) { - if (!(op=get_op(ctx,0,"[","(",".",NULL))) - return; - if (op[0] == '.') { - eval_brace(ctx, &tmp); - if (ctx->error) return; - resolve(ctx, res); - if (ctx->error) return; - res->attrn=tmp.var; - res->attrnlen=tmp.varlen; - dump(res); - } else if (op[0] == '[') { - resolve_object(ctx, res); - if (ctx->error) return; - if (get_op(ctx,0,"@",NULL)) { - if (!ctx->skip) { - struct object_func *obj_func=object_func_lookup(res->attr.type); - struct attr_iter *iter; - struct attr attr; - enum attr_type attr_type=command_attr_type(res); - void *obj=res->attr.u.data; - if (!obj) { - dbg(lvl_error,"no object"); - return; - } - if (!obj_func) { - dbg(lvl_error,"no object func"); - return; - } - if (!obj_func->iter_new || !obj_func->iter_destroy) { - dbg(lvl_error,"no iter func"); - return; - } - iter = obj_func->iter_new(NULL); - result_free(res); - res->varlen=0; - res->attrn=NULL; - while (obj_func->get_attr(obj, attr_type, &attr, iter)) { - if (command_evaluate_to_boolean(&attr, ctx->expr, &ctx->error)) { - result_free(res); - res->attr=attr; - } - } - obj_func->iter_destroy(iter); - } - if (ctx->error) return; - ctx->expr+=command_evaluate_to_length(ctx->expr, &ctx->error); - } - if (!get_op(ctx,0,"]",NULL)) { - ctx->error=missing_closing_bracket; - return; - } - } else if (op[0] == '(') { - dbg(lvl_debug,"function call"); - resolve_object(ctx, res); - command_call_function(ctx, res); - } - } +eval_postfix(struct context *ctx, struct result *res) { + struct result tmp= {{0,},}; + const char *op; + + eval_brace(ctx, res); + if (ctx->error) return; + for (;;) { + if (!(op=get_op(ctx,0,"[","(",".",NULL))) + return; + if (op[0] == '.') { + eval_brace(ctx, &tmp); + if (ctx->error) return; + resolve(ctx, res); + if (ctx->error) return; + res->attrn=tmp.var; + res->attrnlen=tmp.varlen; + dump(res); + } else if (op[0] == '[') { + resolve_object(ctx, res); + if (ctx->error) return; + if (get_op(ctx,0,"@",NULL)) { + if (!ctx->skip) { + struct object_func *obj_func=object_func_lookup(res->attr.type); + struct attr_iter *iter; + struct attr attr; + enum attr_type attr_type=command_attr_type(res); + void *obj=res->attr.u.data; + if (!obj) { + dbg(lvl_error,"no object"); + return; + } + if (!obj_func) { + dbg(lvl_error,"no object func"); + return; + } + if (!obj_func->iter_new || !obj_func->iter_destroy) { + dbg(lvl_error,"no iter func"); + return; + } + iter = obj_func->iter_new(NULL); + result_free(res); + res->varlen=0; + res->attrn=NULL; + while (obj_func->get_attr(obj, attr_type, &attr, iter)) { + if (command_evaluate_to_boolean(&attr, ctx->expr, &ctx->error)) { + result_free(res); + res->attr=attr; + } + } + obj_func->iter_destroy(iter); + } + if (ctx->error) return; + ctx->expr+=command_evaluate_to_length(ctx->expr, &ctx->error); + } + if (!get_op(ctx,0,"]",NULL)) { + ctx->error=missing_closing_bracket; + return; + } + } else if (op[0] == '(') { + dbg(lvl_debug,"function call"); + resolve_object(ctx, res); + command_call_function(ctx, res); + } + } } static void -eval_unary(struct context *ctx, struct result *res) -{ - const char *op; - op=get_op(ctx,0,"~","!",NULL); - if (op) { - eval_unary(ctx, res); - if (ctx->error) return; - result_op(ctx, op_type_prefix, op, res, NULL); - } else - eval_postfix(ctx, res); +eval_unary(struct context *ctx, struct result *res) { + const char *op; + op=get_op(ctx,0,"~","!",NULL); + if (op) { + eval_unary(ctx, res); + if (ctx->error) return; + result_op(ctx, op_type_prefix, op, res, NULL); + } else + eval_postfix(ctx, res); } static void -eval_multiplicative(struct context *ctx, struct result *res) -{ - struct result tmp={{0,},}; - const char *op; - - eval_unary(ctx, res); - if (ctx->error) return; - for (;;) { - if (!(op=get_op(ctx,0,"*","/","%",NULL))) return; - eval_unary(ctx, &tmp); - if (!ctx->error) - result_op(ctx, op_type_binary, op, res, &tmp); - result_free(&tmp); - if (ctx->error) return; - } +eval_multiplicative(struct context *ctx, struct result *res) { + struct result tmp= {{0,},}; + const char *op; + + eval_unary(ctx, res); + if (ctx->error) return; + for (;;) { + if (!(op=get_op(ctx,0,"*","/","%",NULL))) return; + eval_unary(ctx, &tmp); + if (!ctx->error) + result_op(ctx, op_type_binary, op, res, &tmp); + result_free(&tmp); + if (ctx->error) return; + } } static void -eval_additive(struct context *ctx, struct result *res) -{ - struct result tmp={{0,},}; - const char *op; - - eval_multiplicative(ctx, res); - if (ctx->error) return; - for (;;) { - if (!(op=get_op(ctx,0,"-","+",NULL))) return; - eval_multiplicative(ctx, &tmp); - if (!ctx->error) - result_op(ctx, op_type_binary, op, res, &tmp); - result_free(&tmp); - if (ctx->error) return; - } +eval_additive(struct context *ctx, struct result *res) { + struct result tmp= {{0,},}; + const char *op; + + eval_multiplicative(ctx, res); + if (ctx->error) return; + for (;;) { + if (!(op=get_op(ctx,0,"-","+",NULL))) return; + eval_multiplicative(ctx, &tmp); + if (!ctx->error) + result_op(ctx, op_type_binary, op, res, &tmp); + result_free(&tmp); + if (ctx->error) return; + } } static void -eval_equality(struct context *ctx, struct result *res) -{ - struct result tmp={{0,},}; - const char *op; +eval_equality(struct context *ctx, struct result *res) { + struct result tmp= {{0,},}; + const char *op; - eval_additive(ctx, res); - if (ctx->error) return; - for (;;) { - if (!(op=get_op(ctx,0,"==","!=","<=",">=","<",">",NULL))) return; - eval_additive(ctx, &tmp); - if (!ctx->error) - result_op(ctx, op_type_binary, op, res, &tmp); - result_free(&tmp); - if (ctx->error) return; - } + eval_additive(ctx, res); + if (ctx->error) return; + for (;;) { + if (!(op=get_op(ctx,0,"==","!=","<=",">=","<",">",NULL))) return; + eval_additive(ctx, &tmp); + if (!ctx->error) + result_op(ctx, op_type_binary, op, res, &tmp); + result_free(&tmp); + if (ctx->error) return; + } } static void -eval_bitwise_and(struct context *ctx, struct result *res) -{ - struct result tmp={{0,},}; - - eval_equality(ctx, res); - if (ctx->error) return; - for (;;) { - if (get_op(ctx,1,"&&",NULL)) return; - if (!get_op(ctx,0,"&",NULL)) return; - eval_equality(ctx, &tmp); - if (!ctx->error) - result_op(ctx, op_type_binary, "&", res, &tmp); - result_free(&tmp); - if (ctx->error) return; - } +eval_bitwise_and(struct context *ctx, struct result *res) { + struct result tmp= {{0,},}; + + eval_equality(ctx, res); + if (ctx->error) return; + for (;;) { + if (get_op(ctx,1,"&&",NULL)) return; + if (!get_op(ctx,0,"&",NULL)) return; + eval_equality(ctx, &tmp); + if (!ctx->error) + result_op(ctx, op_type_binary, "&", res, &tmp); + result_free(&tmp); + if (ctx->error) return; + } } static void -eval_bitwise_xor(struct context *ctx, struct result *res) -{ - struct result tmp={{0,},}; +eval_bitwise_xor(struct context *ctx, struct result *res) { + struct result tmp= {{0,},}; - eval_bitwise_and(ctx, res); - if (ctx->error) return; - for (;;) { - if (!get_op(ctx,0,"^",NULL)) return; - eval_bitwise_and(ctx, &tmp); - if (!ctx->error) - result_op(ctx, op_type_binary, "^", res, &tmp); - result_free(&tmp); - if (ctx->error) return; - } + eval_bitwise_and(ctx, res); + if (ctx->error) return; + for (;;) { + if (!get_op(ctx,0,"^",NULL)) return; + eval_bitwise_and(ctx, &tmp); + if (!ctx->error) + result_op(ctx, op_type_binary, "^", res, &tmp); + result_free(&tmp); + if (ctx->error) return; + } } static void -eval_bitwise_or(struct context *ctx, struct result *res) -{ - struct result tmp={{0,},}; - - eval_bitwise_xor(ctx, res); - if (ctx->error) return; - for (;;) { - if (get_op(ctx,1,"||",NULL)) return; - if (!get_op(ctx,0,"|",NULL)) return; - eval_bitwise_xor(ctx, &tmp); - if (!ctx->error) - result_op(ctx, op_type_binary, "|", res, &tmp); - result_free(&tmp); - if (ctx->error) return; - } +eval_bitwise_or(struct context *ctx, struct result *res) { + struct result tmp= {{0,},}; + + eval_bitwise_xor(ctx, res); + if (ctx->error) return; + for (;;) { + if (get_op(ctx,1,"||",NULL)) return; + if (!get_op(ctx,0,"|",NULL)) return; + eval_bitwise_xor(ctx, &tmp); + if (!ctx->error) + result_op(ctx, op_type_binary, "|", res, &tmp); + result_free(&tmp); + if (ctx->error) return; + } } static void -eval_logical_and(struct context *ctx, struct result *res) -{ - struct result tmp={{0,},}; +eval_logical_and(struct context *ctx, struct result *res) { + struct result tmp= {{0,},}; - eval_bitwise_or(ctx, res); - if (ctx->error) return; - for (;;) { - if (!get_op(ctx,0,"&&",NULL)) return; - eval_bitwise_or(ctx, &tmp); - if (!ctx->error) - result_op(ctx, op_type_binary, "&&", res, &tmp); - result_free(&tmp); - if (ctx->error) return; - } + eval_bitwise_or(ctx, res); + if (ctx->error) return; + for (;;) { + if (!get_op(ctx,0,"&&",NULL)) return; + eval_bitwise_or(ctx, &tmp); + if (!ctx->error) + result_op(ctx, op_type_binary, "&&", res, &tmp); + result_free(&tmp); + if (ctx->error) return; + } } static void -eval_logical_or(struct context *ctx, struct result *res) -{ - struct result tmp={{0,},}; +eval_logical_or(struct context *ctx, struct result *res) { + struct result tmp= {{0,},}; - eval_logical_and(ctx, res); - if (ctx->error) return; - for (;;) { - if (!get_op(ctx,0,"||",NULL)) return; - eval_logical_and(ctx, &tmp); - if (!ctx->error) - result_op(ctx, op_type_binary, "||", res, &tmp); - result_free(&tmp); - if (ctx->error) return; - } + eval_logical_and(ctx, res); + if (ctx->error) return; + for (;;) { + if (!get_op(ctx,0,"||",NULL)) return; + eval_logical_and(ctx, &tmp); + if (!ctx->error) + result_op(ctx, op_type_binary, "||", res, &tmp); + result_free(&tmp); + if (ctx->error) return; + } } static void -eval_conditional(struct context *ctx, struct result *res) -{ - struct result tmp={{0,},}; - int cond=0; - int skip; - - eval_logical_or(ctx, res); - if (ctx->error) return; - if (!get_op(ctx,0,"?",NULL)) return; - skip=ctx->skip; - cond=get_bool(ctx, res); - result_free(res); - if (ctx->error) return; - ctx->skip=!cond || skip; - eval_logical_or(ctx, &tmp); - ctx->skip=skip; - if (ctx->error) { - result_free(&tmp); - return; - } - - *res=tmp; - memset(&tmp,0,sizeof(tmp)); - - if (!get_op(ctx,0,":",NULL)) { - dbg(lvl_debug,"ctxerr"); - ctx->error=missing_colon; - return; - } - ctx->skip=cond || skip; - eval_logical_or(ctx, &tmp); - ctx->skip=skip; - if (ctx->error) { - result_free(&tmp); - return; - } - if (!cond) { - result_free(res); - *res=tmp; - } else - result_free(&tmp); +eval_conditional(struct context *ctx, struct result *res) { + struct result tmp= {{0,},}; + int cond=0; + int skip; + + eval_logical_or(ctx, res); + if (ctx->error) return; + if (!get_op(ctx,0,"?",NULL)) return; + skip=ctx->skip; + cond=get_bool(ctx, res); + result_free(res); + if (ctx->error) return; + ctx->skip=!cond || skip; + eval_logical_or(ctx, &tmp); + ctx->skip=skip; + if (ctx->error) { + result_free(&tmp); + return; + } + + *res=tmp; + memset(&tmp,0,sizeof(tmp)); + + if (!get_op(ctx,0,":",NULL)) { + dbg(lvl_debug,"ctxerr"); + ctx->error=missing_colon; + return; + } + ctx->skip=cond || skip; + eval_logical_or(ctx, &tmp); + ctx->skip=skip; + if (ctx->error) { + result_free(&tmp); + return; + } + if (!cond) { + result_free(res); + *res=tmp; + } else + result_free(&tmp); } /* = *= /= %= += -= >>= <<= &= ^= |= */ static void -eval_assignment(struct context *ctx, struct result *res) -{ - struct result tmp={{0,},}; - eval_conditional(ctx, res); - if (ctx->error) return; - if (!get_op(ctx,0,"=",NULL)) return; - eval_conditional(ctx, &tmp); - if (ctx->error) { - result_free(&tmp); - return; - } - resolve(ctx, &tmp); - if (ctx->error) { - result_free(&tmp); - return; - } - resolve_object(ctx, res); - command_set_attr(ctx, res, &tmp); +eval_assignment(struct context *ctx, struct result *res) { + struct result tmp= {{0,},}; + eval_conditional(ctx, res); + if (ctx->error) return; + if (!get_op(ctx,0,"=",NULL)) return; + eval_conditional(ctx, &tmp); + if (ctx->error) { + result_free(&tmp); + return; + } + resolve(ctx, &tmp); + if (ctx->error) { + result_free(&tmp); + return; + } + resolve_object(ctx, res); + command_set_attr(ctx, res, &tmp); } /* , */ static void -eval_comma(struct context *ctx, struct result *res) -{ - struct result tmp={{0,},}; +eval_comma(struct context *ctx, struct result *res) { + struct result tmp= {{0,},}; - eval_assignment(ctx, res); - if (ctx->error) return; - for (;;) { - if (!get_op(ctx,0,",",NULL)) return; - eval_assignment(ctx, &tmp); - if (ctx->error) return; - result_free(res); - *res=tmp; - } + eval_assignment(ctx, res); + if (ctx->error) return; + for (;;) { + if (!get_op(ctx,0,",",NULL)) return; + eval_assignment(ctx, &tmp); + if (ctx->error) return; + result_free(res); + *res=tmp; + } } static struct attr ** -eval_list(struct context *ctx) -{ - struct result tmp={{0,},}; - - struct attr **ret=NULL; - for (;;) { - eval_assignment(ctx, &tmp); - if (ctx->error) { - result_free(&tmp); - attr_list_free(ret); - return NULL; - } - resolve(ctx, &tmp); - ret=attr_generic_add_attr(ret, &tmp.attr); - result_free(&tmp); - if (!get_op(ctx,0,",",NULL)) return ret; - } +eval_list(struct context *ctx) { + struct result tmp= {{0,},}; + + struct attr **ret=NULL; + for (;;) { + eval_assignment(ctx, &tmp); + if (ctx->error) { + result_free(&tmp); + attr_list_free(ret); + return NULL; + } + resolve(ctx, &tmp); + ret=attr_generic_add_attr(ret, &tmp.attr); + result_free(&tmp); + if (!get_op(ctx,0,",",NULL)) return ret; + } } #if 0 -void command(struct attr *attr, char *expr) -{ - struct result res; - struct context ctx; - memset(&res, 0, sizeof(res)); - memset(&ctx, 0, sizeof(ctx)); - ctx.attr=attr; - ctx.error=0; - ctx.expr=expr; - printf("command='%s'\n", expr); - eval_comma(&ctx,&res); - printf("err=%d %s\n", ctx.error, ctx.expr); - dump(&res); - printf("***\n"); - resolve(&ctx, &res); - dump(&res); - printf("%s\n", get_string(&ctx, &res)); +void command(struct attr *attr, char *expr) { + struct result res; + struct context ctx; + memset(&res, 0, sizeof(res)); + memset(&ctx, 0, sizeof(ctx)); + ctx.attr=attr; + ctx.error=0; + ctx.expr=expr; + printf("command='%s'\n", expr); + eval_comma(&ctx,&res); + printf("err=%d %s\n", ctx.error, ctx.expr); + dump(&res); + printf("***\n"); + resolve(&ctx, &res); + dump(&res); + printf("%s\n", get_string(&ctx, &res)); } #endif static void -command_evaluate_to(struct attr *attr, const char *expr, struct context *ctx, struct result *res) -{ - result_free(res); - memset(res, 0, sizeof(*res)); - memset(ctx, 0, sizeof(*ctx)); - ctx->attr=attr; - ctx->expr=expr; - eval_comma(ctx,res); +command_evaluate_to(struct attr *attr, const char *expr, struct context *ctx, struct result *res) { + result_free(res); + memset(res, 0, sizeof(*res)); + memset(ctx, 0, sizeof(*ctx)); + ctx->attr=attr; + ctx->expr=expr; + eval_comma(ctx,res); } enum attr_type -command_evaluate_to_attr(struct attr *attr, char *expr, int *error, struct attr *ret) -{ - struct result res={{0,},}; - struct context ctx; - command_evaluate_to(attr, expr, &ctx, &res); - if (ctx.error) - return attr_none; - resolve_object(&ctx, &res); - *ret=res.attr; - dbg(lvl_debug,"type %s",attr_to_name(command_attr_type(&res))); - return command_attr_type(&res); +command_evaluate_to_attr(struct attr *attr, char *expr, int *error, struct attr *ret) { + struct result res={{0,},}; + struct context ctx; + command_evaluate_to(attr, expr, &ctx, &res); + if (ctx.error) + return attr_none; + resolve_object(&ctx, &res); + *ret=res.attr; + dbg(lvl_debug,"type %s",attr_to_name(command_attr_type(&res))); + return command_attr_type(&res); } void -command_evaluate_to_void(struct attr *attr, char *expr, int *error) -{ - struct result res={{0,},}; - struct context ctx; - command_evaluate_to(attr, expr, &ctx, &res); - if (!ctx.error) - resolve(&ctx, &res); - if (error) - *error=ctx.error; - result_free(&res); +command_evaluate_to_void(struct attr *attr, char *expr, int *error) { + struct result res= {{0,},}; + struct context ctx; + command_evaluate_to(attr, expr, &ctx, &res); + if (!ctx.error) + resolve(&ctx, &res); + if (error) + *error=ctx.error; + result_free(&res); } char * -command_evaluate_to_string(struct attr *attr, char *expr, int *error) -{ - struct result res={{0,},}; - struct context ctx; - char *ret=NULL; +command_evaluate_to_string(struct attr *attr, char *expr, int *error) { + struct result res= {{0,},}; + struct context ctx; + char *ret=NULL; - command_evaluate_to(attr, expr, &ctx, &res); - if (!ctx.error) - resolve(&ctx, &res); - if (!ctx.error) - ret=get_string(&ctx, &res); - if (error) - *error=ctx.error; + command_evaluate_to(attr, expr, &ctx, &res); + if (!ctx.error) + resolve(&ctx, &res); + if (!ctx.error) + ret=get_string(&ctx, &res); + if (error) + *error=ctx.error; - result_free(&res); + result_free(&res); - if (ctx.error) - return NULL; - else - return ret; + if (ctx.error) + return NULL; + else + return ret; } int -command_evaluate_to_int(struct attr *attr, char *expr, int *error) -{ - struct result res={{0,},}; - struct context ctx; - int ret=0; +command_evaluate_to_int(struct attr *attr, char *expr, int *error) { + struct result res= {{0,},}; + struct context ctx; + int ret=0; - command_evaluate_to(attr, expr, &ctx, &res); - if (!ctx.error) - resolve(&ctx, &res); - if (!ctx.error) - ret=get_int(&ctx, &res); - if (error) - *error=ctx.error; + command_evaluate_to(attr, expr, &ctx, &res); + if (!ctx.error) + resolve(&ctx, &res); + if (!ctx.error) + ret=get_int(&ctx, &res); + if (error) + *error=ctx.error; - result_free(&res); + result_free(&res); - if (ctx.error) - return 0; - else - return ret; + if (ctx.error) + return 0; + else + return ret; } int -command_evaluate_to_boolean(struct attr *attr, const char *expr, int *error) -{ - struct result res={{0,},}; - struct context ctx; - int ret=0; - - command_evaluate_to(attr, expr, &ctx, &res); - if (!ctx.error) - resolve(&ctx, &res); - if (!ctx.error) { - if (res.attr.type == attr_none) - ret=0; - else if ((res.attr.type >= attr_type_int_begin && res.attr.type <= attr_type_int_end) || - (res.attr.type >= attr_type_double_begin && res.attr.type <= attr_type_double_end)) - ret=get_int(&ctx, &res); - else - ret=res.attr.u.data != NULL; - } - - result_free(&res); - - if (error) - *error=ctx.error; - if (ctx.error) - return 0; - else - return ret; +command_evaluate_to_boolean(struct attr *attr, const char *expr, int *error) { + struct result res= {{0,},}; + struct context ctx; + int ret=0; + + command_evaluate_to(attr, expr, &ctx, &res); + if (!ctx.error) + resolve(&ctx, &res); + if (!ctx.error) { + if (res.attr.type == attr_none) + ret=0; + else if ((res.attr.type >= attr_type_int_begin && res.attr.type <= attr_type_int_end) || + (res.attr.type >= attr_type_double_begin && res.attr.type <= attr_type_double_end)) + ret=get_int(&ctx, &res); + else + ret=res.attr.u.data != NULL; + } + + result_free(&res); + + if (error) + *error=ctx.error; + if (ctx.error) + return 0; + else + return ret; } int -command_evaluate_to_length(const char *expr, int *error) -{ - struct attr attr; - struct result res={{0,},}; - struct context ctx; +command_evaluate_to_length(const char *expr, int *error) { + struct attr attr; + struct result res= {{0,},}; + struct context ctx; + + attr.type=attr_none; + attr.u.data=NULL; + command_evaluate_to(&attr, expr, &ctx, &res); - attr.type=attr_none; - attr.u.data=NULL; - command_evaluate_to(&attr, expr, &ctx, &res); + result_free(&res); - result_free(&res); - - if (!ctx.error) - return ctx.expr-expr; - return 0; + if (!ctx.error) + return ctx.expr-expr; + return 0; } static int -command_evaluate_single(struct context *ctx) -{ - struct result res={{0,},},tmp={{0,},}; - const char *op,*a,*f,*end; - enum attr_type attr_type; - void *obj; - struct object_func *obj_func; - struct attr_iter *iter; - struct attr attr; - int cond=0; - int skip=ctx->skip; - if (!(op=get_op(ctx,0,"foreach","if","{",NULL))) { - eval_comma(ctx,&res); - if (ctx->error) - return 0; - resolve(ctx, &res); - result_free(&res); - if (ctx->error) - return 0; - return get_op(ctx,0,";",NULL) != NULL; - } - switch (op[0]) { - case 'f': - if (!get_op(ctx,0,"(",NULL)) { - ctx->error=missing_opening_parenthesis; - return 0; - } - ctx->skip=1; - a=ctx->expr; - eval_conditional(ctx, &res); - resolve_object(ctx, &res); - ctx->skip=skip; - if (!get_op(ctx,0,";",NULL)) { - ctx->error=missing_semicolon; - return 0; - } - eval_comma(ctx,&res); - attr_type=command_attr_type(&res); - obj=res.attr.u.data; - obj_func=object_func_lookup(res.attr.type); - if (!get_op(ctx,0,")",NULL)) { - ctx->error=missing_closing_parenthesis; - return 0; - } - f=ctx->expr; - ctx->skip=1; - if (!command_evaluate_single(ctx)) { - ctx->skip=skip; - return 0; - } - ctx->skip=skip; - if (ctx->skip) { - result_free(&res); - return 1; - } - end=ctx->expr; - if (!obj) { - dbg(lvl_error,"no object"); - return 0; - } - if (!obj_func) { - dbg(lvl_error,"no object func"); - return 0; - } - if (!obj_func->iter_new || !obj_func->iter_destroy) { - dbg(lvl_error,"no iter func"); - return 0; - } - iter = obj_func->iter_new(NULL); - while (obj_func->get_attr(obj, attr_type, &attr, iter)) { - ctx->expr=a; - eval_conditional(ctx, &res); - resolve_object(ctx, &res); - tmp.attr=attr; - resolve(ctx, &tmp); - if (ctx->error) { - result_free(&tmp); - return 0; - } - command_set_attr(ctx, &res, &tmp); - result_free(&tmp); - ctx->expr=f; - if (!command_evaluate_single(ctx)) { - obj_func->iter_destroy(iter); - return 0; - } - } - obj_func->iter_destroy(iter); - ctx->expr=end; - return 1; - case 'i': - if (!get_op(ctx,0,"(",NULL)) { - ctx->error=missing_opening_parenthesis; - return 0; - } - eval_comma(ctx,&res); - if (!skip && !ctx->error) - cond=get_bool(ctx, &res); - result_free(&res); - if (ctx->error) - return 0; - if (!get_op(ctx,0,")",NULL)) { - ctx->error=missing_closing_parenthesis; - return 0; - } - ctx->skip=!cond || skip; - command_evaluate_single(ctx); - ctx->skip=skip; - if (ctx->error) - return 0; - if (get_op(ctx,0,"else",NULL)) { - ctx->skip=cond || skip; - command_evaluate_single(ctx); - ctx->skip=skip; - if (ctx->error) - return 0; - } - return 1; - case '{': - while (!get_op(ctx,0,"}",NULL)) { - if (!command_evaluate_single(ctx)) - return 0; - } - return 1; - default: - return 0; - } +command_evaluate_single(struct context *ctx) { + struct result res= {{0,},},tmp= {{0,},}; + const char *op,*a,*f,*end; + enum attr_type attr_type; + void *obj; + struct object_func *obj_func; + struct attr_iter *iter; + struct attr attr; + int cond=0; + int skip=ctx->skip; + if (!(op=get_op(ctx,0,"foreach","if","{",NULL))) { + eval_comma(ctx,&res); + if (ctx->error) + return 0; + resolve(ctx, &res); + result_free(&res); + if (ctx->error) + return 0; + return get_op(ctx,0,";",NULL) != NULL; + } + switch (op[0]) { + case 'f': + if (!get_op(ctx,0,"(",NULL)) { + ctx->error=missing_opening_parenthesis; + return 0; + } + ctx->skip=1; + a=ctx->expr; + eval_conditional(ctx, &res); + resolve_object(ctx, &res); + ctx->skip=skip; + if (!get_op(ctx,0,";",NULL)) { + ctx->error=missing_semicolon; + return 0; + } + eval_comma(ctx,&res); + attr_type=command_attr_type(&res); + obj=res.attr.u.data; + obj_func=object_func_lookup(res.attr.type); + if (!get_op(ctx,0,")",NULL)) { + ctx->error=missing_closing_parenthesis; + return 0; + } + f=ctx->expr; + ctx->skip=1; + if (!command_evaluate_single(ctx)) { + ctx->skip=skip; + return 0; + } + ctx->skip=skip; + if (ctx->skip) { + result_free(&res); + return 1; + } + end=ctx->expr; + if (!obj) { + dbg(lvl_error,"no object"); + return 0; + } + if (!obj_func) { + dbg(lvl_error,"no object func"); + return 0; + } + if (!obj_func->iter_new || !obj_func->iter_destroy) { + dbg(lvl_error,"no iter func"); + return 0; + } + iter = obj_func->iter_new(NULL); + while (obj_func->get_attr(obj, attr_type, &attr, iter)) { + ctx->expr=a; + eval_conditional(ctx, &res); + resolve_object(ctx, &res); + tmp.attr=attr; + resolve(ctx, &tmp); + if (ctx->error) { + result_free(&tmp); + return 0; + } + command_set_attr(ctx, &res, &tmp); + result_free(&tmp); + ctx->expr=f; + if (!command_evaluate_single(ctx)) { + obj_func->iter_destroy(iter); + return 0; + } + } + obj_func->iter_destroy(iter); + ctx->expr=end; + return 1; + case 'i': + if (!get_op(ctx,0,"(",NULL)) { + ctx->error=missing_opening_parenthesis; + return 0; + } + eval_comma(ctx,&res); + if (!skip && !ctx->error) + cond=get_bool(ctx, &res); + result_free(&res); + if (ctx->error) + return 0; + if (!get_op(ctx,0,")",NULL)) { + ctx->error=missing_closing_parenthesis; + return 0; + } + ctx->skip=!cond || skip; + command_evaluate_single(ctx); + ctx->skip=skip; + if (ctx->error) + return 0; + if (get_op(ctx,0,"else",NULL)) { + ctx->skip=cond || skip; + command_evaluate_single(ctx); + ctx->skip=skip; + if (ctx->error) + return 0; + } + return 1; + case '{': + while (!get_op(ctx,0,"}",NULL)) { + if (!command_evaluate_single(ctx)) + return 0; + } + return 1; + default: + return 0; + } } void -command_evaluate(struct attr *attr, const char *expr) -{ - /* Once the eval has started we can't rely anymore on the content of - * expr which may be freed when the calling widget is destroyed by a - * subsequent command call. Hence the g_strdup. */ - - char *expr_dup; - char *err = NULL; /* Error description */ - struct context ctx={0,}; - ctx.attr=attr; - ctx.error=0; - ctx.expr=expr_dup=g_strdup(expr); - for (;;) { - if (!command_evaluate_single(&ctx)) - break; - } - if (ctx.error && ctx.error != eof_reached) { - char expr[32]; - strncpy(expr, ctx.expr, 32); - expr[31]='\0'; - err = command_error_to_text(ctx.error); - dbg(lvl_error, "error %s starting at %s", err, expr); - g_free(err); - } - g_free(expr_dup); +command_evaluate(struct attr *attr, const char *expr) { + /* Once the eval has started we can't rely anymore on the content of + * expr which may be freed when the calling widget is destroyed by a + * subsequent command call. Hence the g_strdup. */ + + char *expr_dup; + char *err = NULL; /* Error description */ + struct context ctx= {0,}; + ctx.attr=attr; + ctx.error=0; + ctx.expr=expr_dup=g_strdup(expr); + for (;;) { + if (!command_evaluate_single(&ctx)) + break; + } + if (ctx.error && ctx.error != eof_reached) { + char expr[32]; + strncpy(expr, ctx.expr, 32); + expr[31]='\0'; + err = command_error_to_text(ctx.error); + dbg(lvl_error, "error %s starting at %s", err, expr); + g_free(err); + } + g_free(expr_dup); } #if 0 void -command_interpreter(struct attr *attr) -{ - char buffer[4096]; - int size; - for (;;) { - size=read(0, buffer, 4095); - buffer[size]='\0'; - if (size) { - buffer[size-1]='\0'; - } - command(attr, buffer); - } +command_interpreter(struct attr *attr) { + char buffer[4096]; + int size; + for (;;) { + size=read(0, buffer, 4095); + buffer[size]='\0'; + if (size) { + buffer[size-1]='\0'; + } + command(attr, buffer); + } } #endif static void -command_table_call(struct command_table *table, int count, void *data, char *command, struct attr **in, struct attr ***out, int *valid) -{ - int i; - for (i = 0 ; i < count ; i++) { - if (!strcmp(command,table->command)) { - if (valid) - *valid=1; - table->func(data, command, in, out); - } - table++; - } +command_table_call(struct command_table *table, int count, void *data, char *command, struct attr **in, + struct attr ***out, int *valid) { + int i; + for (i = 0 ; i < count ; i++) { + if (!strcmp(command,table->command)) { + if (valid) + *valid=1; + table->func(data, command, in, out); + } + table++; + } } void -command_add_table_attr(struct command_table *table, int count, void *data, struct attr *attr) -{ - attr->type=attr_callback; - attr->u.callback=callback_new_attr_3(callback_cast(command_table_call),attr_command, table, count, data); +command_add_table_attr(struct command_table *table, int count, void *data, struct attr *attr) { + attr->type=attr_callback; + attr->u.callback=callback_new_attr_3(callback_cast(command_table_call),attr_command, table, count, data); } void -command_add_table(struct callback_list *cbl, struct command_table *table, int count, void *data) -{ - struct attr attr; - command_add_table_attr(table, count, data, &attr); - callback_list_add(cbl, attr.u.callback); +command_add_table(struct callback_list *cbl, struct command_table *table, int count, void *data) { + struct attr attr; + command_add_table_attr(table, count, data, &attr); + callback_list_add(cbl, attr.u.callback); } void -command_saved_set_cb (struct command_saved *cs, struct callback *cb) -{ - cs->cb = cb; +command_saved_set_cb (struct command_saved *cs, struct callback *cb) { + cs->cb = cb; } /** @@ -1636,15 +1587,13 @@ command_saved_set_cb (struct command_saved *cs, struct callback *cb) * {@code get_int(&cs->ctx, &cs->res)}. See {@code get_int()} for a description. */ int -command_saved_get_int (struct command_saved *cs) -{ - return get_int(&cs->ctx, &cs->res); +command_saved_get_int (struct command_saved *cs) { + return get_int(&cs->ctx, &cs->res); } -int -command_saved_error (struct command_saved *cs) -{ - return cs->error; +int +command_saved_error (struct command_saved *cs) { + return cs->error; } /** @@ -1658,26 +1607,25 @@ command_saved_error (struct command_saved *cs) * @param cs The command to evaluate */ static void -command_saved_evaluate_idle (struct command_saved *cs) -{ - dbg(lvl_debug, "enter: cs=%p, cs->command=%s", cs, cs->command); - // Only run once at a time - if (cs->idle_ev) { - event_remove_idle(cs->idle_ev); - cs->idle_ev = NULL; - } +command_saved_evaluate_idle (struct command_saved *cs) { + dbg(lvl_debug, "enter: cs=%p, cs->command=%s", cs, cs->command); + // Only run once at a time + if (cs->idle_ev) { + event_remove_idle(cs->idle_ev); + cs->idle_ev = NULL; + } - command_evaluate_to(&cs->context_attr, cs->command, &cs->ctx, &cs->res); + command_evaluate_to(&cs->context_attr, cs->command, &cs->ctx, &cs->res); - if (!cs->ctx.error) { - cs->error = 0; + if (!cs->ctx.error) { + cs->error = 0; - if (cs->cb) { - callback_call_1(cs->cb, cs); - } - } else { - cs->error = cs->ctx.error; - } + if (cs->cb) { + callback_call_1(cs->cb, cs); + } + } else { + cs->error = cs->ctx.error; + } } /** @@ -1692,23 +1640,22 @@ command_saved_evaluate_idle (struct command_saved *cs) * @param cs The command to evaluate */ static void -command_saved_evaluate(struct command_saved *cs) -{ - dbg(lvl_debug, "enter: cs=%p, cs->async=%d, cs->command=%s", cs, cs->async, cs->command); - if (!cs->async) { - command_saved_evaluate_idle(cs); - return; - } - if (cs->idle_ev) { - // We're already scheduled for reevaluation - return; - } +command_saved_evaluate(struct command_saved *cs) { + dbg(lvl_debug, "enter: cs=%p, cs->async=%d, cs->command=%s", cs, cs->async, cs->command); + if (!cs->async) { + command_saved_evaluate_idle(cs); + return; + } + if (cs->idle_ev) { + // We're already scheduled for reevaluation + return; + } - if (!cs->idle_cb) { - cs->idle_cb = callback_new_1(callback_cast(command_saved_evaluate_idle), cs); - } + if (!cs->idle_cb) { + cs->idle_cb = callback_new_1(callback_cast(command_saved_evaluate_idle), cs); + } - cs->idle_ev = event_add_idle(100, cs->idle_cb); + cs->idle_ev = event_add_idle(100, cs->idle_cb); } /** @@ -1717,42 +1664,42 @@ command_saved_evaluate(struct command_saved *cs) * @param cs The saved command */ static void -command_saved_callbacks_changed(struct command_saved *cs) -{ - // For now, we delete each and every callback and then re-create them - int i; - struct object_func *func; - struct attr attr; +command_saved_callbacks_changed(struct command_saved *cs) { + // For now, we delete each and every callback and then re-create them + int i; + struct object_func *func; + struct attr attr; - dbg(lvl_debug, "enter: cs=%p, cs->async=%d, cs->command=%s", cs, cs->async, cs->command); + dbg(lvl_debug, "enter: cs=%p, cs->async=%d, cs->command=%s", cs, cs->async, cs->command); - if (cs->register_ev) { - event_remove_idle(cs->register_ev); - cs->register_ev = NULL; - } + if (cs->register_ev) { + event_remove_idle(cs->register_ev); + cs->register_ev = NULL; + } - attr.type = attr_callback; + attr.type = attr_callback; - for (i = 0; i < cs->num_cbs; i++) { - func = object_func_lookup(cs->cbs[i].attr.type); - - if (!func->remove_attr) { - dbg(lvl_error, "Could not remove command-evaluation callback because remove_attr is missing for type %i!", cs->cbs[i].attr.type); - continue; - } + for (i = 0; i < cs->num_cbs; i++) { + func = object_func_lookup(cs->cbs[i].attr.type); - attr.u.callback = cs->cbs[i].cb; + if (!func->remove_attr) { + dbg(lvl_error, "Could not remove command-evaluation callback because remove_attr is missing for type %i!", + cs->cbs[i].attr.type); + continue; + } - func->remove_attr(cs->cbs[i].attr.u.data, &attr); - callback_destroy(cs->cbs[i].cb); - } + attr.u.callback = cs->cbs[i].cb; - g_free(cs->cbs); - cs->cbs = NULL; - cs->num_cbs = 0; + func->remove_attr(cs->cbs[i].attr.u.data, &attr); + callback_destroy(cs->cbs[i].cb); + } - // Now, re-create all the callbacks - command_register_callbacks(cs); + g_free(cs->cbs); + cs->cbs = NULL; + cs->num_cbs = 0; + + // Now, re-create all the callbacks + command_register_callbacks(cs); } /** @@ -1773,80 +1720,79 @@ command_saved_callbacks_changed(struct command_saved *cs) * @return True if all callbacks were successfully registered, false if the function failed */ static int -command_register_callbacks(struct command_saved *cs) -{ - struct attr prev; /* The parent of the next object which will be retrieved. */ - struct attr cb_attr; - int status; - struct object_func *func; - struct callback *cb; - int tmpoffset; /* For debugging. Because we work with pointers into the same string instance. +command_register_callbacks(struct command_saved *cs) { + struct attr prev; /* The parent of the next object which will be retrieved. */ + struct attr cb_attr; + int status; + struct object_func *func; + struct callback *cb; + int tmpoffset; /* For debugging. Because we work with pointers into the same string instance. * we can figure out offsets by using simple pointer arithmetics. */ - - dbg(lvl_debug, "enter: cs=%p, cs->async=%d, cs->command=%s", cs, cs->async, cs->command); - cs->ctx.expr = cs->command; - prev = cs->context_attr; - - while ((status = get_next_object(&cs->ctx, &cs->res)) != 0) { - tmpoffset = cs->res.var - cs->command; - cs->ctx.attr = &prev; - resolve(&cs->ctx, &cs->res); - - if (cs->ctx.error) { - /* An error occurred while parsing the command */ - tmpoffset = cs->ctx.expr - cs->command; - dbg(lvl_error, "parsing error: cs=%p, cs->ctx.error=%d", cs, cs->ctx.error); - dbg(lvl_error, "\t%s", cs->command); - dbg(lvl_error, "\t%*s", tmpoffset + 1, "^"); - return 0; - } else if (cs->res.attr.type == attr_none) { - /* We could not resolve an object, perhaps because it has not been created */ - dbg(lvl_error, "could not resolve object in cs=%p:", cs); - dbg(lvl_error, "\t%s", cs->command); - dbg(lvl_error, "\t%*s", tmpoffset + 1, "^"); - return 0; - } - - if (prev.type != attr_none) { - func = object_func_lookup(prev.type); - - if (func->add_attr) { - if (status == 2) { // This is not the final attribute name - cb = callback_new_attr_1(callback_cast(command_saved_callbacks_changed), cs->res.attr.type, (void*)cs); - } else if (status == 1) { // This is the final attribute name - cb = callback_new_attr_1(callback_cast(command_saved_evaluate), cs->res.attr.type, (void*)cs); - cs->ctx.attr = &cs->context_attr; - } else { - dbg(lvl_error, "Error: Strange status returned from get_next_object()"); - } - - cs->num_cbs++; - cs->cbs = g_realloc(cs->cbs, (sizeof(struct command_saved_cb) * cs->num_cbs)); - cs->cbs[cs->num_cbs-1].cb = cb; - cs->cbs[cs->num_cbs-1].attr = prev; - - cb_attr.u.callback = cb; - cb_attr.type = attr_callback; - - func->add_attr(prev.u.data, &cb_attr); - - } else { - dbg(lvl_error, "Could not add callback because add_attr is missing for type %i", prev.type); - } - } - - if (status == 2) { - prev = cs->res.attr; - } else { - prev = cs->context_attr; - } - } - - command_saved_evaluate_idle(cs); - - dbg(lvl_debug, "done: cs=%p, cs->command=%s", cs, cs->command); - return 1; + + dbg(lvl_debug, "enter: cs=%p, cs->async=%d, cs->command=%s", cs, cs->async, cs->command); + cs->ctx.expr = cs->command; + prev = cs->context_attr; + + while ((status = get_next_object(&cs->ctx, &cs->res)) != 0) { + tmpoffset = cs->res.var - cs->command; + cs->ctx.attr = &prev; + resolve(&cs->ctx, &cs->res); + + if (cs->ctx.error) { + /* An error occurred while parsing the command */ + tmpoffset = cs->ctx.expr - cs->command; + dbg(lvl_error, "parsing error: cs=%p, cs->ctx.error=%d", cs, cs->ctx.error); + dbg(lvl_error, "\t%s", cs->command); + dbg(lvl_error, "\t%*s", tmpoffset + 1, "^"); + return 0; + } else if (cs->res.attr.type == attr_none) { + /* We could not resolve an object, perhaps because it has not been created */ + dbg(lvl_error, "could not resolve object in cs=%p:", cs); + dbg(lvl_error, "\t%s", cs->command); + dbg(lvl_error, "\t%*s", tmpoffset + 1, "^"); + return 0; + } + + if (prev.type != attr_none) { + func = object_func_lookup(prev.type); + + if (func->add_attr) { + if (status == 2) { // This is not the final attribute name + cb = callback_new_attr_1(callback_cast(command_saved_callbacks_changed), cs->res.attr.type, (void*)cs); + } else if (status == 1) { // This is the final attribute name + cb = callback_new_attr_1(callback_cast(command_saved_evaluate), cs->res.attr.type, (void*)cs); + cs->ctx.attr = &cs->context_attr; + } else { + dbg(lvl_error, "Error: Strange status returned from get_next_object()"); + } + + cs->num_cbs++; + cs->cbs = g_realloc(cs->cbs, (sizeof(struct command_saved_cb) * cs->num_cbs)); + cs->cbs[cs->num_cbs-1].cb = cb; + cs->cbs[cs->num_cbs-1].attr = prev; + + cb_attr.u.callback = cb; + cb_attr.type = attr_callback; + + func->add_attr(prev.u.data, &cb_attr); + + } else { + dbg(lvl_error, "Could not add callback because add_attr is missing for type %i", prev.type); + } + } + + if (status == 2) { + prev = cs->res.attr; + } else { + prev = cs->context_attr; + } + } + + command_saved_evaluate_idle(cs); + + dbg(lvl_debug, "done: cs=%p, cs->command=%s", cs, cs->command); + return 1; } /** @@ -1859,38 +1805,35 @@ command_register_callbacks(struct command_saved *cs) * in an idle callback */ struct command_saved * -command_saved_attr_new(char *command, struct attr *attr, struct callback *cb, int async) -{ - struct command_saved *ret; +command_saved_attr_new(char *command, struct attr *attr, struct callback *cb, int async) { + struct command_saved *ret; - ret = g_new0(struct command_saved, 1); - dbg(lvl_debug, "enter, ret=%p, command=%s", ret, command); - ret->command = g_strdup(command); - ret->context_attr = *attr; - ret->cb = cb; - ret->error = not_ready; - ret->async = async; + ret = g_new0(struct command_saved, 1); + dbg(lvl_debug, "enter, ret=%p, command=%s", ret, command); + ret->command = g_strdup(command); + ret->context_attr = *attr; + ret->cb = cb; + ret->error = not_ready; + ret->async = async; - if (!command_register_callbacks(ret)) { - // We try this as an idle call again - dbg(lvl_debug, "could not register callbacks, will retry as an idle call"); - ret->register_cb = callback_new_1(callback_cast(command_saved_callbacks_changed), ret); - ret->register_ev = event_add_idle(300, ret->register_cb); - } + if (!command_register_callbacks(ret)) { + // We try this as an idle call again + dbg(lvl_debug, "could not register callbacks, will retry as an idle call"); + ret->register_cb = callback_new_1(callback_cast(command_saved_callbacks_changed), ret); + ret->register_ev = event_add_idle(300, ret->register_cb); + } - return ret; + return ret; } struct command_saved * -command_saved_new(char *command, struct navit *navit, struct callback *cb, int async) -{ - struct attr attr=ATTR_OBJECT(navit, navit); - return command_saved_attr_new(command, &attr, cb, async); +command_saved_new(char *command, struct navit *navit, struct callback *cb, int async) { + struct attr attr=ATTR_OBJECT(navit, navit); + return command_saved_attr_new(command, &attr, cb, async); } -void -command_saved_destroy(struct command_saved *cs) -{ - g_free(cs->command); - g_free(cs); +void +command_saved_destroy(struct command_saved *cs) { + g_free(cs->command); + g_free(cs); } |