summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Kolesa <d.kolesa@samsung.com>2014-08-22 13:10:29 +0100
committerDaniel Kolesa <d.kolesa@samsung.com>2014-08-22 13:10:29 +0100
commit26e1ec3e3247dd53d4002c0d712a8c10078a8ad7 (patch)
tree7f319fec523550c0b57d45d3e1a08d55201bcf57
parent489404c7850a72129068b7a52df36b4fd6e12ee3 (diff)
downloadefl-26e1ec3e3247dd53d4002c0d712a8c10078a8ad7.tar.gz
eolian: fully working database validation
-rw-r--r--src/lib/eolian/database_validate.c141
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;