diff --git a/src/lib/eolian/Eolian.h b/src/lib/eolian/Eolian.h index eea5b0295e..fa37c199d6 100644 --- a/src/lib/eolian/Eolian.h +++ b/src/lib/eolian/Eolian.h @@ -769,6 +769,16 @@ EAPI Eina_Bool eolian_class_dtor_enable_get(const Eolian_Class *klass); */ EAPI const Eolian_Type *eolian_type_find_by_alias(const char *alias); +/* + * @brief Check if a typedef is extern. + * + * @param[in] alias alias of the typedef + * @return EINA_TRUE if it's extern, EINA_FALSE otherwise. + * + * @ingroup Eolian + */ +EAPI Eina_Bool eolian_typedef_is_extern(const char *alias); + /* * @brief Find a struct by name * @@ -897,6 +907,16 @@ EAPI Eina_Bool eolian_type_is_own(const Eolian_Type *tp); */ EAPI Eina_Bool eolian_type_is_const(const Eolian_Type *tp); +/* + * @brief Check if a struct type is extern. + * + * @param[in] tp the type. + * @return EINA_TRUE if it's extern, EINA_FALSE otherwise. + * + * @ingroup Eolian + */ +EAPI Eina_Bool eolian_type_struct_is_extern(const Eolian_Type *tp); + /* * @brief Get the full C type name of the given type with a name. * diff --git a/src/lib/eolian/database_type_api.c b/src/lib/eolian/database_type_api.c index 915cba0310..bbb9e0b5aa 100644 --- a/src/lib/eolian/database_type_api.c +++ b/src/lib/eolian/database_type_api.c @@ -9,9 +9,20 @@ eolian_type_find_by_alias(const char *alias) Eina_Stringshare *shr = eina_stringshare_add(alias); Eolian_Typedef *cl = eina_hash_find(_types, shr); eina_stringshare_del(shr); - return cl?cl->type:NULL; + return cl ? cl->type : NULL; } +EAPI Eina_Bool +eolian_typedef_is_extern(const char *alias) +{ + if (!_types) return EINA_FALSE; + Eina_Stringshare *shr = eina_stringshare_add(alias); + Eolian_Typedef *cl = eina_hash_find(_types, shr); + eina_stringshare_del(shr); + return cl ? cl->is_extern : EINA_FALSE; +} + + EAPI const Eolian_Type * eolian_type_struct_find_by_name(const char *name) { @@ -123,6 +134,13 @@ eolian_type_is_const(const Eolian_Type *tp) return tp->is_const; } +EAPI Eina_Bool +eolian_type_struct_is_extern(const Eolian_Type *tp) +{ + EINA_SAFETY_ON_NULL_RETURN_VAL(tp, EINA_FALSE); + return tp->is_extern; +} + EAPI Eina_Stringshare * eolian_type_c_type_named_get(const Eolian_Type *tp, const char *name) { diff --git a/src/lib/eolian/eo_lexer.h b/src/lib/eolian/eo_lexer.h index 56077cbf71..619aa89e35 100644 --- a/src/lib/eolian/eo_lexer.h +++ b/src/lib/eolian/eo_lexer.h @@ -25,8 +25,8 @@ enum Tokens KW(destructor), KW(eo_prefix), KW(events), KW(func), KW(get), \ KW(implements), KW(interface), KW(keys), KW(legacy), KW(legacy_prefix), \ KW(methods), KW(mixin), KW(own), KW(params), KW(properties), KW(set), \ - KW(type), KW(values), KWAT(in), KWAT(inout), KWAT(nonull), KWAT(out), \ - KWAT(warn_unused), \ + KW(type), KW(values), KWAT(extern), KWAT(in), KWAT(inout), KWAT(nonull), \ + KWAT(out), KWAT(warn_unused), \ \ KW(byte), KW(ubyte), KW(char), KW(short), KW(ushort), KW(int), KW(uint), \ KW(long), KW(ulong), KW(llong), KW(ullong), \ diff --git a/src/lib/eolian/eo_parser.c b/src/lib/eolian/eo_parser.c index d94688fe82..f39bfb6de3 100644 --- a/src/lib/eolian/eo_parser.c +++ b/src/lib/eolian/eo_parser.c @@ -229,10 +229,11 @@ _struct_field_free(Eolian_Struct_Field *def) } static Eolian_Type * -parse_struct(Eo_Lexer *ls, const char *name) +parse_struct(Eo_Lexer *ls, const char *name, Eina_Bool is_extern) { int line = ls->line_number, column = ls->column; Eolian_Type *def = push_type(ls); + def->is_extern = is_extern; def->name = name; def->type = EOLIAN_TYPE_STRUCT; def->fields = eina_hash_string_small_new(EINA_FREE_CB(_struct_field_free)); @@ -314,8 +315,18 @@ parse_type_struct(Eo_Lexer *ls, Eina_Bool allow_struct, Eina_Bool allow_anon) eo_lexer_get(ls); if (allow_struct) { + Eina_Bool is_extern = EINA_FALSE; + if (ls->t.kw == KW_at_extern) + { + is_extern = EINA_TRUE; + eo_lexer_get(ls); + } if (allow_anon && ls->t.token == '{') - return parse_struct(ls, NULL); + { + if (is_extern) + eo_lexer_syntax_error(ls, "extern anonymous struct"); + return parse_struct(ls, NULL, EINA_FALSE); + } check(ls, TOK_VALUE); sname = eina_stringshare_add(ls->t.value); if (eo_lexer_lookahead(ls) == '{') @@ -323,7 +334,7 @@ parse_type_struct(Eo_Lexer *ls, Eina_Bool allow_struct, Eina_Bool allow_anon) if (eo_lexer_get_c_type(ls->t.kw)) eo_lexer_syntax_error(ls, "invalid struct name"); eo_lexer_get(ls); - return parse_struct(ls, sname); + return parse_struct(ls, sname, is_extern); } } else @@ -393,6 +404,11 @@ parse_typedef(Eo_Lexer *ls) { ls->tmp.typedef_def = calloc(1, sizeof(Eolian_Typedef)); eo_lexer_get(ls); + if (ls->t.kw == KW_at_extern) + { + ls->tmp.typedef_def->is_extern = EINA_TRUE; + eo_lexer_get(ls); + } check(ls, TOK_VALUE); ls->tmp.typedef_def->alias = eina_stringshare_add(ls->t.value); eo_lexer_get(ls); @@ -1034,13 +1050,19 @@ parse_unit(Eo_Lexer *ls, Eina_Bool eot) case KW_struct: { const char *name; + Eina_Bool is_extern = EINA_FALSE; eo_lexer_get(ls); + if (ls->t.kw == KW_at_extern) + { + is_extern = EINA_TRUE; + eo_lexer_get(ls); + } check(ls, TOK_VALUE); if (eo_lexer_get_c_type(ls->t.kw)) eo_lexer_syntax_error(ls, "invalid struct name"); name = eina_stringshare_add(ls->t.value); eo_lexer_get(ls); - parse_struct(ls, name); + parse_struct(ls, name, is_extern); pop_type(ls); break; } diff --git a/src/lib/eolian/eolian_database.h b/src/lib/eolian/eolian_database.h index a110b691d9..e09a31ee2f 100644 --- a/src/lib/eolian/eolian_database.h +++ b/src/lib/eolian/eolian_database.h @@ -116,6 +116,7 @@ struct _Eolian_Type }; Eina_Bool is_const :1; Eina_Bool is_own :1; + Eina_Bool is_extern :1; }; struct _Eolian_Implement @@ -134,6 +135,7 @@ typedef struct _Eolian_Typedef { Eina_Stringshare *alias; Eolian_Type *type; + Eina_Bool is_extern :1; } Eolian_Typedef; typedef struct _Eolian_Struct_Field