summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/lib/eolian/Eolian.h178
-rw-r--r--src/lib/eolian/database_type_api.c9
-rw-r--r--src/lib/eolian/database_validate.c22
-rw-r--r--src/lib/eolian/eo_lexer.h14
-rw-r--r--src/lib/eolian/eo_parser.c102
-rw-r--r--src/lib/eolian/eolian_database.c70
-rw-r--r--src/lib/eolian/eolian_database.h15
-rw-r--r--src/tests/eolian/data/error.eo13
-rw-r--r--src/tests/eolian/eolian_parsing.c48
9 files changed, 467 insertions, 4 deletions
diff --git a/src/lib/eolian/Eolian.h b/src/lib/eolian/Eolian.h
index 80ccd1ef94..4c9535dc03 100644
--- a/src/lib/eolian/Eolian.h
+++ b/src/lib/eolian/Eolian.h
@@ -170,6 +170,12 @@ typedef struct _Eolian_Expression Eolian_Expression;
*/
typedef struct _Eolian_Variable Eolian_Variable;
+/* Error information
+ *
+ * @ingroup Eolian
+ */
+typedef struct _Eolian_Error Eolian_Error;
+
/* Struct field information
*
* @ingroup Eolian
@@ -222,7 +228,8 @@ typedef enum
EOLIAN_OBJECT_PART,
EOLIAN_OBJECT_IMPLEMENT,
EOLIAN_OBJECT_CONSTRUCTOR,
- EOLIAN_OBJECT_DOCUMENTATION
+ EOLIAN_OBJECT_DOCUMENTATION,
+ EOLIAN_OBJECT_ERROR
} Eolian_Object_Type;
typedef enum
@@ -276,6 +283,7 @@ typedef enum
EOLIAN_TYPE_VOID,
EOLIAN_TYPE_REGULAR,
EOLIAN_TYPE_CLASS,
+ EOLIAN_TYPE_ERROR,
EOLIAN_TYPE_UNDEFINED
} Eolian_Type_Type;
@@ -1079,6 +1087,16 @@ EAPI const Eolian_Variable *eolian_unit_global_by_name_get(const Eolian_Unit *un
EAPI const Eolian_Variable *eolian_unit_constant_by_name_get(const Eolian_Unit *unit, const char *name);
/*
+ * @brief Get an error declaration in a unit by name.
+ *
+ * @param[in] unit The unit.
+ * @param[in] name the name of the error
+ *
+ * @ingroup Eolian
+ */
+EAPI const Eolian_Error *eolian_unit_error_by_name_get(const Eolian_Unit *unit, const char *name);
+
+/*
* @brief Get an iterator to all constant variables in the Eolian database.
*
* @return the iterator or NULL
@@ -1101,6 +1119,17 @@ EAPI Eina_Iterator *eolian_unit_constants_get(const Eolian_Unit *unit);
EAPI Eina_Iterator *eolian_unit_globals_get(const Eolian_Unit *unit);
/*
+ * @brief Get an iterator to all error declarations in the Eolian database.
+ *
+ * @return the iterator or NULL
+ *
+ * Thanks to internal caching, this is an O(1) operation.
+ *
+ * @ingroup Eolian
+ */
+EAPI Eina_Iterator *eolian_unit_errors_get(const Eolian_Unit *unit);
+
+/*
* @brief Get an alias type declaration within a unit by name.
*
* @param[in] unit The unit.
@@ -1266,6 +1295,19 @@ eolian_state_constant_by_name_get(const Eolian_State *state, const char *name)
}
/*
+ * @brief A helper function to get an error declaration in a state by name.
+ *
+ * @see eolian_unit_error_by_name_get
+ *
+ * @ingroup Eolian
+ */
+static inline const Eolian_Error *
+eolian_state_error_by_name_get(const Eolian_State *state, const char *name)
+{
+ return eolian_unit_error_by_name_get(EOLIAN_UNIT(state), name);
+}
+
+/*
* @brief Get an iterator to all global variables contained in a file.
*
* @param[in] state The state.
@@ -1291,6 +1333,19 @@ EAPI Eina_Iterator *eolian_state_globals_by_file_get(const Eolian_State *state,
EAPI Eina_Iterator *eolian_state_constants_by_file_get(const Eolian_State *state, const char *file_name);
/*
+ * @brief Get an iterator to all error declarations contained in a file.
+ *
+ * @param[in] state The state.
+ * @param[in] file_name The file name.
+ * @return the iterator or NULL
+ *
+ * Thanks to internal caching, this is an O(1) operation.
+ *
+ * @ingroup Eolian
+ */
+EAPI Eina_Iterator *eolian_state_errors_by_file_get(const Eolian_State *state, const char *file_name);
+
+/*
* @brief A helper function to get all globals in a state.
*
* @see eolian_unit_globals_get
@@ -1317,6 +1372,19 @@ eolian_state_constants_get(const Eolian_State *state)
}
/*
+ * @brief A helper function to get all error declarations in a state.
+ *
+ * @see eolian_unit_errors_get
+ *
+ * @ingroup Eolian
+ */
+static inline Eina_Iterator *
+eolian_state_errors_get(const Eolian_State *state)
+{
+ return eolian_unit_errors_get(EOLIAN_UNIT(state));
+}
+
+/*
* @brief A helper function to get an alias in a state by name.
*
* @see eolian_unit_alias_by_name_get
@@ -2704,7 +2772,8 @@ EAPI const Eolian_Type *eolian_type_base_type_get(const Eolian_Type *tp);
*
* The inner types of a complex type form a chain. Therefore, you first retrieve
* the first one via eolian_type_base_type_get and then get the next one via
- * this API function called on the first inner type if necessary.
+ * this API function called on the first inner type if necessary. Another use
+ * for this is with errors, specifying error(Foo, Bar, ...) makes a chain.
*
* @param[in] tp the type.
* @return the next type or NULL.
@@ -2753,6 +2822,16 @@ EAPI const Eolian_Type *eolian_type_aliased_base_get(const Eolian_Type *tp);
EAPI const Eolian_Class *eolian_type_class_get(const Eolian_Type *tp);
/*
+ * @brief Get the error declaration associated with an EOLIAN_TYPE_ERROR type.
+ *
+ * @param[in] tp the type.
+ * @return the error or NULL.
+ *
+ * @ingroup Eolian
+ */
+EAPI const Eolian_Error *eolian_type_error_get(const Eolian_Type *tp);
+
+/*
* @brief Get whether the given type is owned.
*
* This is true when a parameter, return or whatever is marked as @owned.
@@ -3131,6 +3210,101 @@ eolian_variable_is_beta(const Eolian_Variable *var)
}
/*
+ * @brief Get the message of an error declaration.
+ *
+ * @param[in] err the error.
+ * @return the message or NULL.
+ *
+ * @ingroup Eolian
+ */
+EAPI const char *eolian_error_message_get(const Eolian_Error *err);
+
+/*
+ * @brief Get the documentation of an error declaration.
+ *
+ * @param[in] err the error declaration.
+ * @return the documentation or NULL.
+ *
+ * @ingroup Eolian
+ */
+EAPI const Eolian_Documentation *eolian_error_documentation_get(const Eolian_Error *err);
+
+/*
+ * @brief A helper function to get the full name of an error declaration.
+ *
+ * @see eolian_object_name_get
+ *
+ * @ingroup Eolian
+ */
+static inline const char *
+eolian_error_name_get(const Eolian_Error *err)
+{
+ return eolian_object_name_get(EOLIAN_OBJECT(err));
+}
+
+/*
+ * @brief A helper function to get the C name of an error declaration.
+ *
+ * @see eolian_object_c_name_get
+ *
+ * @ingroup Eolian
+ */
+static inline const char *
+eolian_error_c_name_get(const Eolian_Error *err)
+{
+ return eolian_object_c_name_get(EOLIAN_OBJECT(err));
+}
+
+/*
+ * @brief A helper function to get the short name of an error declaration.
+ *
+ * @see eolian_object_short_name_get
+ *
+ * @ingroup Eolian
+ */
+static inline const char *
+eolian_error_short_name_get(const Eolian_Error *err)
+{
+ return eolian_object_short_name_get(EOLIAN_OBJECT(err));
+}
+
+/*
+ * @brief A helper function to get the namespaces of an error declaration.
+ *
+ * @see eolian_object_namespaces_get
+ *
+ * @ingroup Eolian
+ */
+static inline Eina_Iterator *
+eolian_error_namespaces_get(const Eolian_Error *err)
+{
+ return eolian_object_namespaces_get(EOLIAN_OBJECT(err));
+}
+
+/*
+ * @brief Get whether an error declaration is beta.
+ *
+ * @see eolian_object_is_beta
+ *
+ * @ingroup Eolian
+ */
+static inline Eina_Bool
+eolian_error_is_beta(const Eolian_Error *err)
+{
+ return eolian_object_is_beta(EOLIAN_OBJECT(err));
+}
+
+/*
+ * @brief Check if an error declaration is extern.
+ *
+ * @param[in] err the errpr decůaratopm.
+ * @return EINA_TRUE if it's extern, EINA_FALSE otherwise.
+ *
+ * @ingroup Eolian
+ */
+EAPI Eina_Bool eolian_error_is_extern(const Eolian_Error *err);
+
+/*
* @brief Get the summary of the documentation.
*
* This should never return NULL unless the input is invalid.
diff --git a/src/lib/eolian/database_type_api.c b/src/lib/eolian/database_type_api.c
index b10a9a700f..d4869e2866 100644
--- a/src/lib/eolian/database_type_api.c
+++ b/src/lib/eolian/database_type_api.c
@@ -197,6 +197,15 @@ eolian_type_class_get(const Eolian_Type *tp)
return tp->klass;
}
+EAPI const Eolian_Error *
+eolian_type_error_get(const Eolian_Type *tp)
+{
+ EINA_SAFETY_ON_NULL_RETURN_VAL(tp, NULL);
+ if (eolian_type_type_get(tp) != EOLIAN_TYPE_ERROR)
+ return NULL;
+ return tp->error;
+}
+
EAPI Eina_Bool
eolian_type_is_owned(const Eolian_Type *tp)
{
diff --git a/src/lib/eolian/database_validate.c b/src/lib/eolian/database_validate.c
index 71c05d7d8f..8deea6d595 100644
--- a/src/lib/eolian/database_validate.c
+++ b/src/lib/eolian/database_validate.c
@@ -351,9 +351,29 @@ _validate_type(Validate_State *vals, Eolian_Type *tp)
}
if (!tp->freefunc)
tp->freefunc = eina_stringshare_add(eo_obj_free);
- tp->base.c_name = eina_stringshare_ref(tp->tdecl->base.c_name);
+ tp->base.c_name = eina_stringshare_ref(tp->klass->base.c_name);
return _validate_ownable(tp);
}
+ case EOLIAN_TYPE_ERROR:
+ {
+ tp->error = (Eolian_Error *)eolian_unit_error_by_name_get(src, tp->base.name);
+ if (!tp->error)
+ {
+ _eo_parser_log(&tp->base, "undefined error %s "
+ "(likely wrong namespacing)", tp->base.name);
+ return EINA_FALSE;
+ }
+ else if (vals->stable && tp->error->base.is_beta)
+ {
+ _eo_parser_log(&tp->base, "beta error '%s' used in stable context",
+ tp->error->base.name);
+ return EINA_FALSE;
+ }
+ tp->base.c_name = eina_stringshare_ref(tp->error->base.c_name);
+ if (tp->next_type && !_validate_type(vals, tp->next_type))
+ return EINA_FALSE;
+ return _validate(&tp->base);
+ }
default:
return EINA_FALSE;
}
diff --git a/src/lib/eolian/eo_lexer.h b/src/lib/eolian/eo_lexer.h
index 5bc7064151..0e7921726f 100644
--- a/src/lib/eolian/eo_lexer.h
+++ b/src/lib/eolian/eo_lexer.h
@@ -28,7 +28,7 @@ enum Tokens
#define KEYWORDS KW(class), KW(const), KW(enum), KW(return), KW(struct), \
\
KW(abstract), KW(c_prefix), KW(composite), KW(constructor), KW(constructors), \
- KW(data), KW(destructor), KW(event_prefix), KW(events), KW(extends), \
+ KW(data), KW(destructor), KW(error), KW(event_prefix), KW(events), KW(extends), \
KW(free), KW(get), KW(implements), KW(import), KW(interface), \
KW(keys), KW(legacy), KW(methods), KW(mixin), KW(params), \
KW(parse), KW(parts), KW(ptr), KW(set), KW(type), KW(values), KW(var), KW(requires), \
@@ -296,6 +296,18 @@ eo_lexer_expr_release_ref(Eo_Lexer *ls, Eolian_Expression *expr)
return eo_lexer_expr_release(ls, expr);
}
+static inline Eolian_Error *
+eo_lexer_error_new(Eo_Lexer *ls)
+{
+ return (Eolian_Error *)eo_lexer_node_new(ls, sizeof(Eolian_Error));
+}
+
+static inline Eolian_Error *
+eo_lexer_error_release(Eo_Lexer *ls, Eolian_Error *err)
+{
+ return (Eolian_Error *)eo_lexer_node_release(ls, (Eolian_Object *)err);
+}
+
/* "stack" management, only to protect against errors (jumps) in parsing */
void eo_lexer_dtor_push(Eo_Lexer *ls, Eina_Free_Cb free_cb, void *data);
void eo_lexer_dtor_pop(Eo_Lexer *ls);
diff --git a/src/lib/eolian/eo_parser.c b/src/lib/eolian/eo_parser.c
index ee056b7cf5..f33db75f67 100644
--- a/src/lib/eolian/eo_parser.c
+++ b/src/lib/eolian/eo_parser.c
@@ -646,6 +646,29 @@ parse_enum(Eo_Lexer *ls, const char *name, Eina_Bool is_extern,
return def;
}
+/* error(Error1, Error2, Error3, ...) */
+static Eolian_Type *
+parse_type_error(Eo_Lexer *ls)
+{
+ Eolian_Type *def = eo_lexer_type_new(ls);
+ Eina_Strbuf *buf = eina_strbuf_new();
+ eo_lexer_dtor_push(ls, EINA_FREE_CB(eina_strbuf_free), buf);
+ for (Eolian_Type *cdef = def;; cdef = cdef->next_type)
+ {
+ FILL_BASE(cdef->base, ls, ls->line_number, ls->column, TYPE);
+ parse_name(ls, buf);
+ cdef->type = EOLIAN_TYPE_ERROR;
+ cdef->base.name = eina_stringshare_add(eina_strbuf_string_get(buf));
+ eina_strbuf_reset(buf);
+ if (ls->t.token != ',')
+ break;
+ eo_lexer_get(ls);
+ cdef->next_type = eo_lexer_type_release(ls, eo_lexer_type_new(ls));
+ }
+ eo_lexer_dtor_pop(ls);
+ return def;
+}
+
static Eolian_Type *
parse_type_void(Eo_Lexer *ls, Eina_Bool allow_ptr)
{
@@ -698,6 +721,17 @@ parse_type_void(Eo_Lexer *ls, Eina_Bool allow_ptr)
check_match(ls, ')', '(', pline, pcolumn);
return def;
}
+ case KW_error:
+ {
+ int pline, pcolumn;
+ eo_lexer_get(ls);
+ pline = ls->line_number;
+ pcolumn = ls->column;
+ check_next(ls, '(');
+ def = parse_type_error(ls);
+ check_match(ls, ')', '(', pline, pcolumn);
+ return def;
+ }
default:
break;
}
@@ -910,6 +944,71 @@ tags_done:
return def;
}
+static Eolian_Error *
+parse_error(Eo_Lexer *ls)
+{
+ Eolian_Error *def = eo_lexer_error_new(ls);
+ Eina_Strbuf *buf;
+ eo_lexer_get(ls);
+ Eina_Stringshare *cname = NULL;
+ Eina_Bool has_extern = EINA_FALSE, has_beta = EINA_FALSE, has_c_name = EINA_FALSE;
+ for (;;) switch (ls->t.kw)
+ {
+ case KW_at_extern:
+ CASE_LOCK(ls, extern, "extern qualifier");
+ def->is_extern = EINA_TRUE;
+ eo_lexer_get(ls);
+ break;
+ case KW_at_beta:
+ CASE_LOCK(ls, beta, "beta qualifier");
+ def->base.is_beta = EINA_TRUE;
+ eo_lexer_get(ls);
+ break;
+ case KW_at_c_name:
+ CASE_LOCK(ls, c_name, "@c_name specifier");
+ cname = parse_c_name(ls);
+ eo_lexer_dtor_push(ls, EINA_FREE_CB(eina_stringshare_del), (void *)cname);
+ break;
+ default:
+ goto tags_done;
+ }
+tags_done:
+ buf = eina_strbuf_new();
+ eo_lexer_dtor_push(ls, EINA_FREE_CB(eina_strbuf_free), buf);
+ eo_lexer_context_push(ls);
+ FILL_BASE(def->base, ls, ls->line_number, ls->column, ERROR);
+ parse_name(ls, buf);
+ def->base.name = eina_stringshare_add(eina_strbuf_string_get(buf));
+ if (cname)
+ {
+ def->base.c_name = cname;
+ eo_lexer_dtor_pop(ls);
+ }
+ else
+ def->base.c_name = make_c_name(def->base.name);
+ Eolian_Object *decl = _eolian_decl_get(ls, def->base.name);
+ if (decl)
+ {
+ eo_lexer_context_restore(ls);
+ redef_error(ls, decl, &def->base);
+ }
+ eo_lexer_context_pop(ls);
+ check(ls, '=');
+ /* we need to parse a string so switch to exprmode */
+ ls->expr_mode = EINA_TRUE;
+ /* consume = to get string */
+ eo_lexer_get(ls);
+ /* verify and switch back to plain syntax mode */
+ check(ls, TOK_STRING);
+ ls->expr_mode = EINA_FALSE;
+ def->msg = eina_stringshare_ref(ls->t.value.s);
+ eo_lexer_get(ls);
+ check_next(ls, ';');
+ FILL_DOC(ls, def, doc);
+ eo_lexer_dtor_pop(ls);
+ return def;
+}
+
typedef struct _Eo_Ret_Def
{
Eolian_Type *type;
@@ -2273,6 +2372,9 @@ parse_unit(Eo_Lexer *ls, Eina_Bool eot)
parse_variable(ls, ls->t.kw == KW_var)));
break;
}
+ case KW_error:
+ database_error_add(ls->unit, eo_lexer_error_release(ls, parse_error(ls)));
+ break;
case KW_struct:
case KW_enum:
{
diff --git a/src/lib/eolian/eolian_database.c b/src/lib/eolian/eolian_database.c
index 40b0ca156f..caa43407a4 100644
--- a/src/lib/eolian/eolian_database.c
+++ b/src/lib/eolian/eolian_database.c
@@ -568,6 +568,7 @@ database_unit_init(Eolian_State *state, Eolian_Unit *unit, const char *file)
unit->classes = eina_hash_stringshared_new(EINA_FREE_CB(database_class_del));
unit->globals = eina_hash_stringshared_new(EINA_FREE_CB(database_var_del));
unit->constants = eina_hash_stringshared_new(EINA_FREE_CB(database_var_del));
+ unit->errors = eina_hash_stringshared_new(EINA_FREE_CB(database_error_del));
unit->aliases = eina_hash_stringshared_new(EINA_FREE_CB(database_typedecl_del));
unit->structs = eina_hash_stringshared_new(EINA_FREE_CB(database_typedecl_del));
unit->enums = eina_hash_stringshared_new(EINA_FREE_CB(database_typedecl_del));
@@ -585,6 +586,7 @@ _unit_contents_del(Eolian_Unit *unit)
eina_hash_free(unit->classes);
eina_hash_free(unit->globals);
eina_hash_free(unit->constants);
+ eina_hash_free(unit->errors);
eina_hash_free(unit->aliases);
eina_hash_free(unit->structs);
eina_hash_free(unit->enums);
@@ -637,6 +639,7 @@ _state_area_init(Eolian_State *state, Eolian_State_Area *a)
a->enums_f = eina_hash_stringshared_new(NULL);
a->globals_f = eina_hash_stringshared_new(NULL);
a->constants_f = eina_hash_stringshared_new(NULL);
+ a->errors_f = eina_hash_stringshared_new(NULL);
a->objects_f = eina_hash_stringshared_new(NULL);
}
@@ -663,6 +666,7 @@ _state_area_contents_del(Eolian_State_Area *a)
_hashlist_free(a->enums_f);
_hashlist_free(a->globals_f);
_hashlist_free(a->constants_f);
+ _hashlist_free(a->errors_f);
_hashlist_free(a->objects_f);
}
@@ -1240,6 +1244,17 @@ eolian_state_constants_by_file_get(const Eolian_State *state, const char *file_n
}
EAPI Eina_Iterator *
+eolian_state_errors_by_file_get(const Eolian_State *state, const char *file_name)
+{
+ if (!state) return NULL;
+ Eina_Stringshare *shr = eina_stringshare_add(file_name);
+ Eina_List *l = eina_hash_find(state->main.errors_f, shr);
+ eina_stringshare_del(shr);
+ if (!l) return NULL;
+ return eina_list_iterator_new(l);
+}
+
+EAPI Eina_Iterator *
eolian_state_aliases_by_file_get(const Eolian_State *state, const char *file_name)
{
if (!state) return NULL;
@@ -1361,6 +1376,16 @@ eolian_unit_constant_by_name_get(const Eolian_Unit *unit, const char *name)
return v;
}
+EAPI const Eolian_Error *
+eolian_unit_error_by_name_get(const Eolian_Unit *unit, const char *name)
+{
+ if (!unit) return NULL;
+ Eina_Stringshare *shr = eina_stringshare_add(name);
+ Eolian_Error *v = eina_hash_find(unit->errors, shr);
+ eina_stringshare_del(shr);
+ return v;
+}
+
EAPI Eina_Iterator *
eolian_unit_constants_get(const Eolian_Unit *unit)
{
@@ -1373,6 +1398,12 @@ eolian_unit_globals_get(const Eolian_Unit *unit)
return (unit ? eina_hash_iterator_data_new(unit->globals) : NULL);
}
+EAPI Eina_Iterator *
+eolian_unit_errors_get(const Eolian_Unit *unit)
+{
+ return (unit ? eina_hash_iterator_data_new(unit->errors) : NULL);
+}
+
EAPI const Eolian_Typedecl *
eolian_unit_alias_by_name_get(const Eolian_Unit *unit, const char *name)
{
@@ -1424,6 +1455,45 @@ eolian_unit_enums_get(const Eolian_Unit *unit)
return (unit ? eina_hash_iterator_data_new(unit->enums) : NULL);
}
+EAPI const char *
+eolian_error_message_get(const Eolian_Error *err)
+{
+ if (!err) return NULL;
+ return err->msg;
+}
+
+EAPI Eina_Bool
+eolian_error_is_extern(const Eolian_Error *err)
+{
+ if (!err) return EINA_FALSE;
+ return err->is_extern;
+}
+
+EAPI const Eolian_Documentation *
+eolian_error_documentation_get(const Eolian_Error *err)
+{
+ EINA_SAFETY_ON_NULL_RETURN_VAL(err, NULL);
+ return err->doc;
+}
+
+void
+database_error_del(Eolian_Error *err)
+{
+ if (!err || eolian_object_unref(&err->base)) return;
+ eina_stringshare_del(err->msg);
+ free(err);
+}
+
+void
+database_error_add(Eolian_Unit *unit, Eolian_Error *err)
+{
+ EOLIAN_OBJECT_ADD(unit, err->base.name, err, errors);
+ eina_hash_set(unit->state->staging.errors_f, err->base.file, eina_list_append
+ ((Eina_List*)eina_hash_find(unit->state->staging.errors_f, err->base.file),
+ err));
+ database_object_add(unit, &err->base);
+}
+
char *
database_class_to_filename(const char *cname)
{
diff --git a/src/lib/eolian/eolian_database.h b/src/lib/eolian/eolian_database.h
index 0dce769370..950e4114d4 100644
--- a/src/lib/eolian/eolian_database.h
+++ b/src/lib/eolian/eolian_database.h
@@ -41,6 +41,7 @@ struct _Eolian_Unit
Eina_Hash *classes;
Eina_Hash *globals;
Eina_Hash *constants;
+ Eina_Hash *errors;
Eina_Hash *aliases;
Eina_Hash *structs;
Eina_Hash *enums;
@@ -60,6 +61,7 @@ typedef struct _Eolian_State_Area
Eina_Hash *enums_f;
Eina_Hash *globals_f;
Eina_Hash *constants_f;
+ Eina_Hash *errors_f;
Eina_Hash *objects_f;
} Eolian_State_Area;
@@ -267,6 +269,7 @@ struct _Eolian_Type
{
Eolian_Class *klass;
Eolian_Typedecl *tdecl;
+ Eolian_Error *error;
};
Eina_Bool is_const :1;
Eina_Bool is_ptr :1;
@@ -325,6 +328,14 @@ struct _Eolian_Event
Eina_Bool is_restart :1;
};
+struct _Eolian_Error
+{
+ Eolian_Object base;
+ Eina_Stringshare *msg;
+ Eolian_Documentation *doc;
+ Eina_Bool is_extern :1;
+};
+
struct _Eolian_Struct_Type_Field
{
Eolian_Object base;
@@ -448,4 +459,8 @@ void database_event_del(Eolian_Event *event);
/* parts */
void database_part_del(Eolian_Part *part);
+/* errors */
+void database_error_del(Eolian_Error *err);
+void database_error_add(Eolian_Unit *unit, Eolian_Error *err);
+
#endif
diff --git a/src/tests/eolian/data/error.eo b/src/tests/eolian/data/error.eo
new file mode 100644
index 0000000000..3a5867ac8d
--- /dev/null
+++ b/src/tests/eolian/data/error.eo
@@ -0,0 +1,13 @@
+error Foo = "something bad happened"; [[Error doc]]
+error @beta Bar = "another bad thing happened"; [[Another error doc]]
+
+class @beta Error {
+ methods {
+ foo {
+ return: error(Foo);
+ }
+ bar {
+ return: error(Foo, Bar);
+ }
+ }
+}
diff --git a/src/tests/eolian/eolian_parsing.c b/src/tests/eolian/eolian_parsing.c
index 57120f6253..ccabb263fd 100644
--- a/src/tests/eolian/eolian_parsing.c
+++ b/src/tests/eolian/eolian_parsing.c
@@ -843,6 +843,53 @@ EFL_START_TEST(eolian_var)
}
EFL_END_TEST
+EFL_START_TEST(eolian_error)
+{
+ const Eolian_Unit *unit;
+ const Eolian_Class *class;
+ const Eolian_Function *f1, *f2;
+ const Eolian_Type *rtp1, *rtp2;
+ const Eolian_Error *err1, *err2;
+
+ Eolian_State *eos = eolian_state_new();
+
+ fail_if(!eolian_state_directory_add(eos, TESTS_SRC_DIR"/data"));
+ fail_if(!(unit = eolian_state_file_parse(eos, "error.eo")));
+
+ fail_if(!(class = eolian_unit_class_by_name_get(unit, "Error")));
+ fail_if(!(f1 = eolian_class_function_by_name_get(class, "foo", EOLIAN_METHOD)));
+ fail_if(!(f2 = eolian_class_function_by_name_get(class, "bar", EOLIAN_METHOD)));
+
+ fail_if(!(rtp1 = eolian_function_return_type_get(f1, EOLIAN_METHOD)));
+ fail_if(!(rtp2 = eolian_function_return_type_get(f2, EOLIAN_METHOD)));
+
+ /* single error */
+ fail_if(eolian_type_type_get(rtp1) != EOLIAN_TYPE_ERROR);
+ fail_if(eolian_type_next_type_get(rtp1) != NULL);
+ fail_if(strcmp(eolian_type_name_get(rtp1), "Foo"));
+ fail_if(!(err1 = eolian_type_error_get(rtp1)));
+ fail_if(strcmp(eolian_error_message_get(err1), "something bad happened"));
+
+ /* error range */
+ fail_if(eolian_type_type_get(rtp2) != EOLIAN_TYPE_ERROR);
+ fail_if(!(rtp1 = eolian_type_next_type_get(rtp2)));
+ fail_if(strcmp(eolian_type_name_get(rtp2), "Foo"));
+ fail_if(strcmp(eolian_type_name_get(rtp1), "Bar"));
+ /* it's the same Foo here */
+ fail_if(eolian_type_error_get(rtp2) != err1);
+ fail_if(!(err2 = eolian_type_error_get(rtp1)));
+ fail_if(strcmp(eolian_error_message_get(err1), "something bad happened"));
+ fail_if(strcmp(eolian_error_message_get(err2), "another bad thing happened"));
+
+ fail_if(!eolian_error_documentation_get(err1));
+ fail_if(!eolian_error_documentation_get(err2));
+ fail_if(eolian_error_is_beta(err1));
+ fail_if(!eolian_error_is_beta(err2));
+
+ eolian_state_free(eos);
+}
+EFL_END_TEST
+
EFL_START_TEST(eolian_enum)
{
const Eolian_Enum_Type_Field *field = NULL;
@@ -1621,6 +1668,7 @@ void eolian_parsing_test(TCase *tc)
tcase_add_test(tc, eolian_struct);
tcase_add_test(tc, eolian_extern);
tcase_add_test(tc, eolian_var);
+ tcase_add_test(tc, eolian_error);
tcase_add_test(tc, eolian_enum);
tcase_add_test(tc, eolian_class_funcs);
tcase_add_test(tc, eolian_free_func);