diff options
author | Daniel Kolesa <d.kolesa@samsung.com> | 2014-08-22 13:10:29 +0100 |
---|---|---|
committer | Daniel Kolesa <d.kolesa@samsung.com> | 2014-08-22 13:10:29 +0100 |
commit | 26e1ec3e3247dd53d4002c0d712a8c10078a8ad7 (patch) | |
tree | 7f319fec523550c0b57d45d3e1a08d55201bcf57 | |
parent | 489404c7850a72129068b7a52df36b4fd6e12ee3 (diff) | |
download | efl-26e1ec3e3247dd53d4002c0d712a8c10078a8ad7.tar.gz |
eolian: fully working database validation
-rw-r--r-- | src/lib/eolian/database_validate.c | 141 |
1 files changed, 132 insertions, 9 deletions
diff --git a/src/lib/eolian/database_validate.c b/src/lib/eolian/database_validate.c index d8932c2deb..620f9b1153 100644 --- a/src/lib/eolian/database_validate.c +++ b/src/lib/eolian/database_validate.c @@ -1,18 +1,141 @@ -#include "eolian_database.h" +#include "eo_lexer.h" + +static Eina_Bool _validate_type(const Eolian_Type *tp); +static Eina_Bool _validate_expr(const Eolian_Expression *expr, + const Eolian_Type *tp, + Eolian_Expression_Mask msk); + +static Eina_Bool +_sf_map_cb(const Eina_Hash *hash EINA_UNUSED, const void *key EINA_UNUSED, + const Eolian_Struct_Field *sf, Eina_Bool *success) +{ + *success = _validate_type(sf->type); + return *success; +} + +static Eina_Bool +_ef_map_cb(const Eina_Hash *hash EINA_UNUSED, const void *key EINA_UNUSED, + const Eolian_Enum_Field *ef, Eina_Bool *success) +{ + *success = _validate_expr(ef->value, NULL, EOLIAN_MASK_INT); + return *success; +} + +static Eina_Bool +_type_error(const Eolian_Type *tp, const char *msg) +{ + eina_log_print(_eolian_log_dom, EINA_LOG_LEVEL_WARN, tp->base.file, "", + tp->base.line, "%s at column %d", msg, tp->base.column); + return EINA_FALSE; +} static Eina_Bool _validate_type(const Eolian_Type *tp) { - (void)tp; + switch (tp->type) + { + case EOLIAN_TYPE_VOID: + return EINA_TRUE; + case EOLIAN_TYPE_REGULAR: + { + const Eolian_Type *tpp; + /* builtins */ + int id = eo_lexer_keyword_str_to_id(tp->full_name); + if (id) + return eo_lexer_is_type_keyword(id); + /* user defined */ + tpp = eolian_type_alias_get_by_name(tp->full_name); + if (!tpp) + { + char buf[256]; + snprintf(buf, sizeof(buf), "undefined alias %s", tp->full_name); + _type_error(tp, buf); + return EINA_TRUE; /* for now only warn */ + } + return _validate_type(tpp); + } + case EOLIAN_TYPE_REGULAR_STRUCT: + { + const Eolian_Type *tpp; + tpp = eolian_type_struct_get_by_name(tp->full_name); + if (!tpp) + { + char buf[256]; + snprintf(buf, sizeof(buf), "undefined struct %s", tp->full_name); + _type_error(tp, buf); + return EINA_TRUE; /* for now only warn */ + } + return _validate_type(tpp); + } + case EOLIAN_TYPE_REGULAR_ENUM: + { + const Eolian_Type *tpp; + tpp = eolian_type_enum_get_by_name(tp->full_name); + if (!tpp) + { + char buf[256]; + snprintf(buf, sizeof(buf), "undefined enum %s", tp->full_name); + _type_error(tp, buf); + return EINA_TRUE; /* for now only warn */ + } + return _validate_type(tpp); + } + case EOLIAN_TYPE_POINTER: + case EOLIAN_TYPE_ALIAS: + return _validate_type(tp->base_type); + case EOLIAN_TYPE_FUNCTION: + { + Eina_List *l; + Eolian_Type *tpp; + if (!_validate_type(tp->ret_type)) + return EINA_FALSE; + EINA_LIST_FOREACH(tp->arguments, l, tpp) + if (!_validate_type(tpp)) + return EINA_FALSE; + return EINA_TRUE; + } + case EOLIAN_TYPE_STRUCT: + { + Eina_Bool succ = EINA_TRUE; + eina_hash_foreach(tp->fields, (Eina_Hash_Foreach)_sf_map_cb, &succ); + return succ; + } + case EOLIAN_TYPE_STRUCT_OPAQUE: + return EINA_TRUE; + case EOLIAN_TYPE_ENUM: + { + Eina_Bool succ = EINA_TRUE; + eina_hash_foreach(tp->fields, (Eina_Hash_Foreach)_ef_map_cb, &succ); + return succ; + } + case EOLIAN_TYPE_CLASS: + { + if (!eolian_type_class_get(tp)) + { + /* for now only warn */ + char buf[256]; + snprintf(buf, sizeof(buf), "undefined class %s " + "(likely wrong namespacing)", tp->full_name); + _type_error(tp, buf); + } + return EINA_TRUE; + } + default: + return EINA_FALSE; + } return EINA_TRUE; } static Eina_Bool -_validate_expr(const Eolian_Expression *expr, const Eolian_Type *tp) +_validate_expr(const Eolian_Expression *expr, const Eolian_Type *tp, + Eolian_Expression_Mask msk) { - (void)expr; - (void)tp; - return EINA_TRUE; + Eolian_Value val; + if (tp) + val = eolian_expression_eval_type(expr, tp); + else + val = eolian_expression_eval(expr, msk); + return (val.type == EOLIAN_EXPR_UNKNOWN); } static Eina_Bool @@ -37,11 +160,11 @@ _validate_function(const Eolian_Function *func) return EINA_FALSE; if (func->get_ret_val && !_validate_expr(func->get_ret_val, - func->get_ret_type)) + func->get_ret_type, 0)) return EINA_FALSE; if (func->set_ret_val && !_validate_expr(func->set_ret_val, - func->set_ret_type)) + func->set_ret_type, 0)) return EINA_FALSE; EINA_LIST_FOREACH(func->keys, l, param) @@ -95,7 +218,7 @@ _validate_variable(const Eolian_Variable *var) if (!_validate_type(var->base_type)) return EINA_FALSE; - if (var->value && !_validate_expr(var->value, var->base_type)) + if (var->value && !_validate_expr(var->value, var->base_type, 0)) return EINA_FALSE; return EINA_TRUE; |