eolian: fully working database validation
This commit is contained in:
parent
489404c785
commit
26e1ec3e32
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue