EOLIAN_EXPR_NULL,
EOLIAN_EXPR_BOOL,
EOLIAN_EXPR_NAME,
+ EOLIAN_EXPR_ENUM,
EOLIAN_EXPR_UNARY,
EOLIAN_EXPR_BINARY
} Eolian_Expression_Type;
return node_error((const Eolian_Object*)expr, buf);
}
+static Eina_Bool
+expr_error(const Eolian_Expression *expr, const char *msg)
+{
+ char buf[512];
+ snprintf(buf, sizeof(buf), "%s '%s'", msg, expr->value.s);
+ return node_error((const Eolian_Object*)expr, buf);
+}
+
static int
expr_type_to_mask(const Eolian_Expression *expr)
{
}
static Eina_Bool
+split_enum_name(const char *str, char **ename, char **memb)
+{
+ char *fulln = strdup(str);
+ char *memb_s = strrchr(fulln, '.');
+ if (!memb_s)
+ {
+ free(fulln);
+ return EINA_FALSE;
+ }
+ *(memb_s++) = '\0';
+ *ename = fulln;
+ *memb = memb_s;
+ return EINA_TRUE;
+}
+
+static Eina_Bool
eval_exp(const Eolian_Expression *expr, Eolian_Expression_Mask mask,
Eolian_Expression *out)
{
*out = *expr;
return EINA_TRUE;
}
+ case EOLIAN_EXPR_NAME:
+ {
+ const Eolian_Variable *var = eolian_variable_constant_get_by_name
+ (expr->value.s);
+ const Eolian_Expression *exp = NULL;
+
+ if (!var)
+ {
+ const Eolian_Type *etp;
+
+ /* try aliases, hoping it'll be enum */
+ char *fulln = NULL, *memb = NULL;
+
+ if (!split_enum_name(expr->value.s, &fulln, &memb))
+ return expr_error(expr, "undefined variable");
+
+ etp = eolian_type_alias_get_by_name(fulln);
+ while (etp && etp->type == EOLIAN_TYPE_ALIAS)
+ {
+ etp = eolian_type_base_type_get(etp);
+ if (etp->type == EOLIAN_TYPE_ENUM)
+ break;
+ if (etp->type == EOLIAN_TYPE_REGULAR_ENUM)
+ break;
+ if (etp->type != EOLIAN_TYPE_REGULAR)
+ {
+ etp = NULL;
+ break;
+ }
+ etp = eolian_type_alias_get_by_name(etp->full_name);
+ }
+
+ if (etp && etp->type == EOLIAN_TYPE_REGULAR_ENUM)
+ etp = eolian_type_enum_get_by_name(etp->full_name);
+
+ if (!etp || etp->type != EOLIAN_TYPE_ENUM)
+ {
+ free(fulln);
+ return expr_error(expr, "undefined variable");
+ }
+
+ exp = eolian_type_enum_field_get(etp, memb);
+ free(fulln);
+
+ if (!exp)
+ return expr_error(expr, "invalid enum field");
+ }
+ else
+ exp = var->value;
+
+ if (!exp)
+ return expr_error(expr, "undefined variable");
+
+ return eval_exp(exp, mask, out);
+ }
+ case EOLIAN_EXPR_ENUM:
+ {
+ const Eolian_Type *etp;
+ const Eolian_Expression *exp;
+
+ char *fulln = NULL, *memb = NULL;
+ if (!split_enum_name(expr->value.s, &fulln, &memb))
+ {
+ return expr_error(expr, "invalid enum");
+ }
+
+ etp = eolian_type_enum_get_by_name(fulln);
+ if (etp && etp->type == EOLIAN_TYPE_REGULAR_ENUM)
+ etp = eolian_type_enum_get_by_name(etp->full_name);
+
+ if (!etp)
+ {
+ free(fulln);
+ return expr_error(expr, "invalid enum");
+ }
+
+ exp = eolian_type_enum_field_get(etp, memb);
+ free(fulln);
+
+ if (!exp)
+ return expr_error(expr, "invalid enum field");
+
+ return eval_exp(exp, mask, out);
+ }
case EOLIAN_EXPR_UNARY:
return eval_unary(expr, mask, out);
case EOLIAN_EXPR_BINARY:
{
if (!tp) return;
Eolian_Type *btp = tp->base_type;
- /* prevent deletion of named structs as they're deleted later on */
- if (btp && btp->type == EOLIAN_TYPE_STRUCT && btp->name)
- tp->base_type = NULL;
+ /* prevent deletion of named structs/enums as they're deleted later on */
+ if (btp)
+ {
+ if (btp->type == EOLIAN_TYPE_ENUM)
+ tp->base_type = NULL;
+ else if (btp->type == EOLIAN_TYPE_STRUCT && btp->name)
+ tp->base_type = NULL;
+ }
database_type_del(tp);
}
return EINA_TRUE;
}
+Eina_Bool database_enum_add(Eolian_Type *tp)
+{
+ if (!_enums) return EINA_FALSE;
+ eina_hash_set(_enums, tp->full_name, tp);
+ eina_hash_set(_enumsf, tp->base.file, eina_list_append
+ ((Eina_List*)eina_hash_find(_enumsf, tp->base.file), tp));
+ return EINA_TRUE;
+}
+
static void
_ftype_to_str(const Eolian_Type *tp, Eina_Strbuf *buf, const char *name)
{
return tp;
}
+EAPI const Eolian_Type *
+eolian_type_enum_get_by_name(const char *name)
+{
+ if (!_enums) return NULL;
+ Eina_Stringshare *shr = eina_stringshare_add(name);
+ Eolian_Type *tp = eina_hash_find(_enums, shr);
+ eina_stringshare_del(shr);
+ return tp;
+}
+
EAPI Eina_Iterator *
eolian_type_aliases_get_by_file(const char *fname)
{
return eina_list_iterator_new(l);
}
+EAPI Eina_Iterator *
+eolian_type_enums_get_by_file(const char *fname)
+{
+ if (!_structsf) return NULL;
+ Eina_Stringshare *shr = eina_stringshare_add(fname);
+ Eina_List *l = eina_hash_find(_enumsf, shr);
+ eina_stringshare_del(shr);
+ if (!l) return NULL;
+ return eina_list_iterator_new(l);
+}
+
EAPI Eolian_Type_Type
eolian_type_type_get(const Eolian_Type *tp)
{
return sf->comment;
}
+EAPI Eina_Iterator *
+eolian_type_enum_field_names_get(const Eolian_Type *tp)
+{
+ EINA_SAFETY_ON_NULL_RETURN_VAL(tp, NULL);
+ EINA_SAFETY_ON_FALSE_RETURN_VAL(tp->type == EOLIAN_TYPE_ENUM, NULL);
+ return eina_hash_iterator_key_new(tp->fields);
+}
+
+EAPI Eina_Bool
+eolian_type_enum_field_exists(const Eolian_Type *tp, const char *field)
+{
+ Eolian_Enum_Field *ef = NULL;
+ EINA_SAFETY_ON_NULL_RETURN_VAL(tp, EINA_FALSE);
+ EINA_SAFETY_ON_FALSE_RETURN_VAL(tp->type == EOLIAN_TYPE_ENUM, EINA_FALSE);
+ ef = eina_hash_find(tp->fields, field);
+ if (!ef)
+ return EINA_FALSE;
+ return EINA_TRUE;
+}
+
+EAPI const Eolian_Expression *
+eolian_type_enum_field_get(const Eolian_Type *tp, const char *field)
+{
+ Eolian_Enum_Field *ef = NULL;
+ EINA_SAFETY_ON_NULL_RETURN_VAL(tp, NULL);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(field, NULL);
+ EINA_SAFETY_ON_FALSE_RETURN_VAL(tp->type == EOLIAN_TYPE_ENUM, NULL);
+ ef = eina_hash_find(tp->fields, field);
+ if (!ef) return NULL;
+ return ef->value;
+}
+
+EAPI Eina_Stringshare *
+eolian_type_enum_field_description_get(const Eolian_Type *tp, const char *field)
+{
+ Eolian_Enum_Field *ef = NULL;
+ EINA_SAFETY_ON_NULL_RETURN_VAL(tp, NULL);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(field, NULL);
+ EINA_SAFETY_ON_FALSE_RETURN_VAL(tp->type == EOLIAN_TYPE_ENUM, NULL);
+ ef = eina_hash_find(tp->fields, field);
+ if (!ef) return NULL;
+ return ef->comment;
+}
+
EAPI Eina_Stringshare *
eolian_type_description_get(const Eolian_Type *tp)
{
eo_lexer_get(ls);
break;
}
+ case KW_enum:
default:
{
Eina_Strbuf *buf = push_strbuf(ls);
+ Eolian_Expression_Type tp = EOLIAN_EXPR_NAME;
+ if (ls->t.kw == KW_enum)
+ {
+ eo_lexer_get(ls);
+ tp = EOLIAN_EXPR_ENUM;
+ }
expr = push_expr(ls);
- expr->type = EOLIAN_EXPR_NAME;
+ expr->type = tp;
parse_name(ls, buf);
expr->value.s = eina_stringshare_add(eina_strbuf_string_get
(buf));
def->base.file = eina_stringshare_ref(ls->filename);
def->base.line = line;
def->base.column = column;
- if (name) database_struct_add(def);
+ if (name) database_enum_add(def);
return def;
}