summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Kolesa <d.kolesa@osg.samsung.com>2016-06-30 14:04:03 +0100
committerDaniel Kolesa <d.kolesa@osg.samsung.com>2016-06-30 16:59:21 +0100
commitab2e608239d0518241454bd7cb6abe3f680764c1 (patch)
tree950be0f34dffe5e3962c6f850e54bd770459fd21
parentff7a5e4f1b1286b1226fb0a9a1729759d1f72e18 (diff)
eolian: add support for static and terminated arrays
Adds two new type types, STATIC_ARRAY and TERMINATED_ARRAY. Static arrays are only allowed as struct members right now - they translate to regular C static arrays (allowing them elsewhere wouldn't be good, as C isn't very good at working with the size information). Terminated arrays are basically sequences of data terminated at the end. The base type of static arrays can be any type that is not marked ref (explicit ref may get allowed later). The base type of terminated arrays has the same restriction plus that it has to be either implicitly reference type (i.e. translating to pointer in C), integer type or a character. In case of ref types, the terminator is NULL. In case of integer types, the terminator is a zero. In case of character types, the terminator is also a zero (null terminator like C strings). @feature
-rw-r--r--src/bin/eolian/types_generator.c21
-rw-r--r--src/bindings/luajit/eolian.lua23
-rw-r--r--src/lib/eolian/Eolian.h12
-rw-r--r--src/lib/eolian/database_type.c3
-rw-r--r--src/lib/eolian/database_type_api.c7
-rw-r--r--src/lib/eolian/database_validate.c2
-rw-r--r--src/lib/eolian/eo_lexer.c5
-rw-r--r--src/lib/eolian/eo_lexer.h2
-rw-r--r--src/lib/eolian/eo_parser.c124
-rw-r--r--src/lib/eolian/eolian_database.h1
-rw-r--r--src/tests/eolian/data/struct.eo2
-rw-r--r--src/tests/eolian/data/struct_ref.c2
-rw-r--r--src/tests/eolian/eolian_parsing.c15
13 files changed, 180 insertions, 39 deletions
diff --git a/src/bin/eolian/types_generator.c b/src/bin/eolian/types_generator.c
index 5995405..241da0a 100644
--- a/src/bin/eolian/types_generator.c
+++ b/src/bin/eolian/types_generator.c
@@ -70,10 +70,23 @@ _type_generate(const Eolian_Typedecl *tp, Eina_Bool full, Eina_Bool use_legacy)
70 EINA_ITERATOR_FOREACH(members, member) 70 EINA_ITERATOR_FOREACH(members, member)
71 { 71 {
72 const Eolian_Type *type = eolian_typedecl_struct_field_type_get(member); 72 const Eolian_Type *type = eolian_typedecl_struct_field_type_get(member);
73 Eina_Stringshare *c_type = eolian_type_c_type_get(type); 73 Eina_Stringshare *c_type = NULL;
74 eina_strbuf_append_printf(buf, " %s%s%s;", 74 if (eolian_type_type_get(type) == EOLIAN_TYPE_STATIC_ARRAY)
75 c_type, strchr(c_type, '*')?"":" ", 75 {
76 eolian_typedecl_struct_field_name_get(member)); 76 c_type = eolian_type_c_type_get(eolian_type_base_type_get(type));
77 eina_strbuf_append_printf(buf, " %s%s%s[%zu];",
78 c_type, strchr(c_type, '*')?"":" ",
79 eolian_typedecl_struct_field_name_get(member),
80 eolian_type_array_size_get(type));
81 }
82 else
83 {
84 c_type = eolian_type_c_type_get(type);
85 eina_strbuf_append_printf(buf, " %s%s%s;",
86 c_type, strchr(c_type, '*')?"":" ",
87 eolian_typedecl_struct_field_name_get(member));
88 }
89 eina_stringshare_del(c_type);
77 const Eolian_Documentation *fdoc 90 const Eolian_Documentation *fdoc
78 = eolian_typedecl_struct_field_documentation_get(member); 91 = eolian_typedecl_struct_field_documentation_get(member);
79 if (fdoc) 92 if (fdoc)
diff --git a/src/bindings/luajit/eolian.lua b/src/bindings/luajit/eolian.lua
index 4f8a1c9..9cd7050 100644
--- a/src/bindings/luajit/eolian.lua
+++ b/src/bindings/luajit/eolian.lua
@@ -76,6 +76,8 @@ ffi.cdef [[
76 EOLIAN_TYPE_COMPLEX, 76 EOLIAN_TYPE_COMPLEX,
77 EOLIAN_TYPE_POINTER, 77 EOLIAN_TYPE_POINTER,
78 EOLIAN_TYPE_CLASS, 78 EOLIAN_TYPE_CLASS,
79 EOLIAN_TYPE_STATIC_ARRAY,
80 EOLIAN_TYPE_TERMINATED_ARRAY,
79 EOLIAN_TYPE_UNDEFINED 81 EOLIAN_TYPE_UNDEFINED
80 } Eolian_Type_Type; 82 } Eolian_Type_Type;
81 83
@@ -300,6 +302,7 @@ ffi.cdef [[
300 const Eolian_Type *eolian_typedecl_aliased_base_get(const Eolian_Typedecl *tp); 302 const Eolian_Type *eolian_typedecl_aliased_base_get(const Eolian_Typedecl *tp);
301 303
302 const Eolian_Class *eolian_type_class_get(const Eolian_Type *tp); 304 const Eolian_Class *eolian_type_class_get(const Eolian_Type *tp);
305 size_t eolian_type_array_size_get(const Eolian_Type *tp);
303 Eina_Bool eolian_type_is_own(const Eolian_Type *tp); 306 Eina_Bool eolian_type_is_own(const Eolian_Type *tp);
304 Eina_Bool eolian_type_is_const(const Eolian_Type *tp); 307 Eina_Bool eolian_type_is_const(const Eolian_Type *tp);
305 Eina_Bool eolian_type_is_ref(const Eolian_Type *tp); 308 Eina_Bool eolian_type_is_ref(const Eolian_Type *tp);
@@ -448,13 +451,15 @@ M.declaration_type = {
448} 451}
449 452
450M.type_type = { 453M.type_type = {
451 UNKNOWN = 0, 454 UNKNOWN = 0,
452 VOID = 1, 455 VOID = 1,
453 REGULAR = 2, 456 REGULAR = 2,
454 COMPLEX = 3, 457 COMPLEX = 3,
455 POINTER = 4, 458 POINTER = 4,
456 CLASS = 5, 459 CLASS = 5,
457 UNDEFINED = 6 460 STATIC_ARRAY = 6,
461 TERMINATED_ARRAY = 7,
462 UNDEFINED = 8
458} 463}
459 464
460M.typedecl_type = { 465M.typedecl_type = {
@@ -650,6 +655,10 @@ M.Type = ffi.metatype("Eolian_Type", {
650 return v 655 return v
651 end, 656 end,
652 657
658 array_size_get = function(self)
659 return tonumber(eolian.eolian_type_array_size_get(self))
660 end,
661
653 is_own = function(self) 662 is_own = function(self)
654 return eolian.eolian_type_is_own(self) ~= 0 663 return eolian.eolian_type_is_own(self) ~= 0
655 end, 664 end,
diff --git a/src/lib/eolian/Eolian.h b/src/lib/eolian/Eolian.h
index 8039337..59eb0f6 100644
--- a/src/lib/eolian/Eolian.h
+++ b/src/lib/eolian/Eolian.h
@@ -220,6 +220,8 @@ typedef enum
220 EOLIAN_TYPE_COMPLEX, 220 EOLIAN_TYPE_COMPLEX,
221 EOLIAN_TYPE_POINTER, 221 EOLIAN_TYPE_POINTER,
222 EOLIAN_TYPE_CLASS, 222 EOLIAN_TYPE_CLASS,
223 EOLIAN_TYPE_STATIC_ARRAY,
224 EOLIAN_TYPE_TERMINATED_ARRAY,
223 EOLIAN_TYPE_UNDEFINED 225 EOLIAN_TYPE_UNDEFINED
224} Eolian_Type_Type; 226} Eolian_Type_Type;
225 227
@@ -1727,6 +1729,16 @@ EAPI const Eolian_Type *eolian_type_aliased_base_get(const Eolian_Type *tp);
1727EAPI const Eolian_Class *eolian_type_class_get(const Eolian_Type *tp); 1729EAPI const Eolian_Class *eolian_type_class_get(const Eolian_Type *tp);
1728 1730
1729/* 1731/*
1732 * @brief Get the size of an EOLIAN_TYPE_STATIC_ARRAY.
1733 *
1734 * @param[in] tp the type.
1735 * @return the size or 0.
1736 *
1737 * @ingroup Eolian
1738 */
1739EAPI size_t eolian_type_array_size_get(const Eolian_Type *tp);
1740
1741/*
1730 * @brief Get whether the given type is owned. 1742 * @brief Get whether the given type is owned.
1731 * 1743 *
1732 * @param[in] tp the type. 1744 * @param[in] tp the type.
diff --git a/src/lib/eolian/database_type.c b/src/lib/eolian/database_type.c
index ee1f114..d0e6423 100644
--- a/src/lib/eolian/database_type.c
+++ b/src/lib/eolian/database_type.c
@@ -101,9 +101,10 @@ database_type_to_str(const Eolian_Type *tp, Eina_Strbuf *buf, const char *name)
101 eina_strbuf_append(buf, "__undefined_type"); 101 eina_strbuf_append(buf, "__undefined_type");
102 else 102 else
103 { 103 {
104 /* handles arrays and pointers as they all serialize to pointers */
104 Eolian_Type *btp = tp->base_type; 105 Eolian_Type *btp = tp->base_type;
105 database_type_to_str(tp->base_type, buf, NULL); 106 database_type_to_str(tp->base_type, buf, NULL);
106 if (btp->type != EOLIAN_TYPE_POINTER || btp->is_const) 107 if (eina_strbuf_string_get(buf)[eina_strbuf_length_get(buf) - 1] != '*')
107 eina_strbuf_append_char(buf, ' '); 108 eina_strbuf_append_char(buf, ' ');
108 eina_strbuf_append_char(buf, '*'); 109 eina_strbuf_append_char(buf, '*');
109 if (tp->is_const) eina_strbuf_append(buf, " const"); 110 if (tp->is_const) eina_strbuf_append(buf, " const");
diff --git a/src/lib/eolian/database_type_api.c b/src/lib/eolian/database_type_api.c
index 6afe870..4411f8a 100644
--- a/src/lib/eolian/database_type_api.c
+++ b/src/lib/eolian/database_type_api.c
@@ -313,6 +313,13 @@ eolian_type_class_get(const Eolian_Type *tp)
313 return eolian_class_get_by_name(tp->full_name); 313 return eolian_class_get_by_name(tp->full_name);
314} 314}
315 315
316EAPI size_t
317eolian_type_array_size_get(const Eolian_Type *tp)
318{
319 EINA_SAFETY_ON_NULL_RETURN_VAL(tp, 0);
320 return tp->static_size;
321}
322
316EAPI Eina_Bool 323EAPI Eina_Bool
317eolian_type_is_own(const Eolian_Type *tp) 324eolian_type_is_own(const Eolian_Type *tp)
318{ 325{
diff --git a/src/lib/eolian/database_validate.c b/src/lib/eolian/database_validate.c
index b9657ee..aab20a5 100644
--- a/src/lib/eolian/database_validate.c
+++ b/src/lib/eolian/database_validate.c
@@ -242,6 +242,8 @@ _validate_type(const Validator *vs, const Eolian_Type *tp)
242 return _validate_typedecl(vs, tpp); 242 return _validate_typedecl(vs, tpp);
243 } 243 }
244 case EOLIAN_TYPE_POINTER: 244 case EOLIAN_TYPE_POINTER:
245 case EOLIAN_TYPE_STATIC_ARRAY:
246 case EOLIAN_TYPE_TERMINATED_ARRAY:
245 return _validate_type(vs, tp->base_type); 247 return _validate_type(vs, tp->base_type);
246 case EOLIAN_TYPE_CLASS: 248 case EOLIAN_TYPE_CLASS:
247 { 249 {
diff --git a/src/lib/eolian/eo_lexer.c b/src/lib/eolian/eo_lexer.c
index 1a0d9bd..a3a4d4d 100644
--- a/src/lib/eolian/eo_lexer.c
+++ b/src/lib/eolian/eo_lexer.c
@@ -72,6 +72,8 @@ static const char * const ctypes[] =
72 72
73 "void", 73 "void",
74 74
75 NULL, NULL, /* array types */
76
75 "Eina_Accessor", "Eina_Array", "Eina_Iterator", "Eina_Hash", "Eina_List", 77 "Eina_Accessor", "Eina_Array", "Eina_Iterator", "Eina_Hash", "Eina_List",
76 "Eina_Promise", 78 "Eina_Promise",
77 "Eina_Value", "const char *", "Eina_Stringshare *", 79 "Eina_Value", "const char *", "Eina_Stringshare *",
@@ -943,7 +945,6 @@ lex(Eo_Lexer *ls, Eo_Token *tok)
943 { 945 {
944 int dcol = ls->column; 946 int dcol = ls->column;
945 next_char(ls); 947 next_char(ls);
946 if (!ls->expr_mode) return '.';
947 if (!isdigit(ls->current)) return '.'; 948 if (!isdigit(ls->current)) return '.';
948 eina_strbuf_reset(ls->buff); 949 eina_strbuf_reset(ls->buff);
949 eina_strbuf_append_char(ls->buff, '.'); 950 eina_strbuf_append_char(ls->buff, '.');
@@ -959,7 +960,7 @@ lex(Eo_Lexer *ls, Eo_Token *tok)
959 next_char(ls); 960 next_char(ls);
960 continue; 961 continue;
961 } 962 }
962 else if (ls->expr_mode && isdigit(ls->current)) 963 else if (isdigit(ls->current))
963 { 964 {
964 int col = ls->column; 965 int col = ls->column;
965 eina_strbuf_reset(ls->buff); 966 eina_strbuf_reset(ls->buff);
diff --git a/src/lib/eolian/eo_lexer.h b/src/lib/eolian/eo_lexer.h
index 5105288..cc36d77 100644
--- a/src/lib/eolian/eo_lexer.h
+++ b/src/lib/eolian/eo_lexer.h
@@ -50,6 +50,8 @@ enum Tokens
50 \ 50 \
51 KW(void), \ 51 KW(void), \
52 \ 52 \
53 KW(static_array), KW(terminated_array), \
54 \
53 KW(accessor), KW(array), KW(iterator), KW(hash), KW(list), \ 55 KW(accessor), KW(array), KW(iterator), KW(hash), KW(list), \
54 KW(promise), \ 56 KW(promise), \
55 KW(generic_value), KW(string), KW(stringshare), \ 57 KW(generic_value), KW(string), KW(stringshare), \
diff --git a/src/lib/eolian/eo_parser.c b/src/lib/eolian/eo_parser.c
index 8f92002..ead4183 100644
--- a/src/lib/eolian/eo_parser.c
+++ b/src/lib/eolian/eo_parser.c
@@ -187,7 +187,7 @@ static Eina_Strbuf *
187parse_name(Eo_Lexer *ls, Eina_Strbuf *buf) 187parse_name(Eo_Lexer *ls, Eina_Strbuf *buf)
188{ 188{
189 check(ls, TOK_VALUE); 189 check(ls, TOK_VALUE);
190 if (eo_lexer_get_c_type(ls->t.kw)) 190 if (eo_lexer_is_type_keyword(ls->t.kw))
191 eo_lexer_syntax_error(ls, "invalid name"); 191 eo_lexer_syntax_error(ls, "invalid name");
192 eina_strbuf_reset(buf); 192 eina_strbuf_reset(buf);
193 for (;;) 193 for (;;)
@@ -198,7 +198,7 @@ parse_name(Eo_Lexer *ls, Eina_Strbuf *buf)
198 eo_lexer_get(ls); 198 eo_lexer_get(ls);
199 eina_strbuf_append(buf, "."); 199 eina_strbuf_append(buf, ".");
200 check(ls, TOK_VALUE); 200 check(ls, TOK_VALUE);
201 if (eo_lexer_get_c_type(ls->t.kw)) 201 if (eo_lexer_is_type_keyword(ls->t.kw))
202 eo_lexer_syntax_error(ls, "invalid name"); 202 eo_lexer_syntax_error(ls, "invalid name");
203 } 203 }
204 return buf; 204 return buf;
@@ -460,14 +460,15 @@ parse_expr(Eo_Lexer *ls)
460 return parse_expr_bin(ls, 1); 460 return parse_expr_bin(ls, 1);
461} 461}
462 462
463static Eolian_Type *parse_type_void(Eo_Lexer *ls, Eina_Bool allow_ref); 463static Eolian_Type *parse_type_void(Eo_Lexer *ls, Eina_Bool allow_ref,
464 Eina_Bool allow_sarray);
464 465
465static Eolian_Type * 466static Eolian_Type *
466parse_type(Eo_Lexer *ls, Eina_Bool allow_ref) 467parse_type(Eo_Lexer *ls, Eina_Bool allow_ref, Eina_Bool allow_sarray)
467{ 468{
468 Eolian_Type *ret; 469 Eolian_Type *ret;
469 eo_lexer_context_push(ls); 470 eo_lexer_context_push(ls);
470 ret = parse_type_void(ls, allow_ref); 471 ret = parse_type_void(ls, allow_ref, allow_sarray);
471 if (ret->type == EOLIAN_TYPE_VOID) 472 if (ret->type == EOLIAN_TYPE_VOID)
472 { 473 {
473 eo_lexer_context_restore(ls); 474 eo_lexer_context_restore(ls);
@@ -516,7 +517,7 @@ parse_struct(Eo_Lexer *ls, const char *name, Eina_Bool is_extern,
516 def->field_list = eina_list_append(def->field_list, fdef); 517 def->field_list = eina_list_append(def->field_list, fdef);
517 eo_lexer_get(ls); 518 eo_lexer_get(ls);
518 check_next(ls, ':'); 519 check_next(ls, ':');
519 tp = parse_type(ls, EINA_TRUE); 520 tp = parse_type(ls, EINA_TRUE, EINA_TRUE);
520 FILL_BASE(fdef->base, ls, fline, fcol); 521 FILL_BASE(fdef->base, ls, fline, fcol);
521 fdef->type = tp; 522 fdef->type = tp;
522 fdef->name = eina_stringshare_ref(fname); 523 fdef->name = eina_stringshare_ref(fname);
@@ -693,6 +694,18 @@ _parse_dep(Eo_Lexer *ls, const char *fname, const char *name)
693 } 694 }
694} 695}
695 696
697static const Eina_Bool _ownable_types[] = {
698 EINA_FALSE, /* unknown */
699 EINA_FALSE, /* void */
700 EINA_FALSE, /* regular */
701 EINA_TRUE, /* complex */
702 EINA_TRUE, /* pointer */
703 EINA_TRUE, /* class */
704 EINA_TRUE, /* static array */
705 EINA_TRUE, /* terminated array */
706 EINA_FALSE /* undefined */
707};
708
696static Eina_Bool 709static Eina_Bool
697_type_is_ownable(Eolian_Type *tp) 710_type_is_ownable(Eolian_Type *tp)
698{ 711{
@@ -706,13 +719,25 @@ _type_is_ownable(Eolian_Type *tp)
706 return EINA_FALSE; 719 return EINA_FALSE;
707 return (ct[strlen(ct) - 1] == '*'); 720 return (ct[strlen(ct) - 1] == '*');
708 } 721 }
709 return (tp->type == EOLIAN_TYPE_POINTER || 722 return _ownable_types[tp->type];
710 tp->type == EOLIAN_TYPE_COMPLEX || 723}
711 tp->type == EOLIAN_TYPE_CLASS); 724
725static Eina_Bool
726_type_is_terminatable(Eolian_Type *tp)
727{
728 if (_type_is_ownable(tp))
729 return EINA_TRUE;
730 if (tp->type == EOLIAN_TYPE_REGULAR)
731 {
732 int kwid = eo_lexer_keyword_str_to_id(tp->name);
733 /* don't include bool, it only has 2 values so it's useless */
734 return (kwid >= KW_byte && kwid < KW_bool);
735 }
736 return EINA_FALSE;
712} 737}
713 738
714static Eolian_Type * 739static Eolian_Type *
715parse_type_void(Eo_Lexer *ls, Eina_Bool allow_ref) 740parse_type_void(Eo_Lexer *ls, Eina_Bool allow_ref, Eina_Bool allow_sarray)
716{ 741{
717 Eolian_Type *def; 742 Eolian_Type *def;
718 Eina_Strbuf *buf; 743 Eina_Strbuf *buf;
@@ -726,7 +751,7 @@ parse_type_void(Eo_Lexer *ls, Eina_Bool allow_ref)
726 pline = ls->line_number; 751 pline = ls->line_number;
727 pcol = ls->column; 752 pcol = ls->column;
728 check_next(ls, '('); 753 check_next(ls, '(');
729 def = parse_type_void(ls, allow_ref); 754 def = parse_type_void(ls, allow_ref, EINA_FALSE);
730 FILL_BASE(def->base, ls, line, col); 755 FILL_BASE(def->base, ls, line, col);
731 def->is_const = EINA_TRUE; 756 def->is_const = EINA_TRUE;
732 check_match(ls, ')', '(', pline, pcol); 757 check_match(ls, ')', '(', pline, pcol);
@@ -739,7 +764,7 @@ parse_type_void(Eo_Lexer *ls, Eina_Bool allow_ref)
739 pline = ls->line_number; 764 pline = ls->line_number;
740 pcol = ls->column; 765 pcol = ls->column;
741 check_next(ls, '('); 766 check_next(ls, '(');
742 def = parse_type_void(ls, EINA_FALSE); 767 def = parse_type_void(ls, EINA_FALSE, EINA_FALSE);
743 FILL_BASE(def->base, ls, line, col); 768 FILL_BASE(def->base, ls, line, col);
744 def->is_ref = EINA_TRUE; 769 def->is_ref = EINA_TRUE;
745 check_match(ls, ')', '(', pline, pcol); 770 check_match(ls, ')', '(', pline, pcol);
@@ -753,7 +778,7 @@ parse_type_void(Eo_Lexer *ls, Eina_Bool allow_ref)
753 pcolumn = ls->column; 778 pcolumn = ls->column;
754 check_next(ls, '('); 779 check_next(ls, '(');
755 eo_lexer_context_push(ls); 780 eo_lexer_context_push(ls);
756 def = parse_type_void(ls, allow_ref); 781 def = parse_type_void(ls, allow_ref, EINA_FALSE);
757 if (!_type_is_ownable(def)) 782 if (!_type_is_ownable(def))
758 { 783 {
759 eo_lexer_context_restore(ls); 784 eo_lexer_context_restore(ls);
@@ -773,7 +798,7 @@ parse_type_void(Eo_Lexer *ls, Eina_Bool allow_ref)
773 pcolumn = ls->column; 798 pcolumn = ls->column;
774 check_next(ls, '('); 799 check_next(ls, '(');
775 eo_lexer_context_push(ls); 800 eo_lexer_context_push(ls);
776 def = parse_type_void(ls, allow_ref); 801 def = parse_type_void(ls, allow_ref, EINA_FALSE);
777 if (!_type_is_ownable(def)) 802 if (!_type_is_ownable(def))
778 { 803 {
779 eo_lexer_context_restore(ls); 804 eo_lexer_context_restore(ls);
@@ -803,12 +828,61 @@ parse_type_void(Eo_Lexer *ls, Eina_Bool allow_ref)
803 def->type = EOLIAN_TYPE_UNDEFINED; 828 def->type = EOLIAN_TYPE_UNDEFINED;
804 eo_lexer_get(ls); 829 eo_lexer_get(ls);
805 } 830 }
831 else if (ls->t.kw == KW_static_array)
832 {
833 if (!allow_sarray)
834 eo_lexer_syntax_error(ls, "static arrays not allowed in this context");
835 def->type = EOLIAN_TYPE_STATIC_ARRAY;
836 eo_lexer_get(ls);
837 check_next(ls, '<');
838 def->base_type = parse_type(ls, EINA_FALSE, EINA_FALSE);
839 pop_type(ls);
840 check_next(ls, ',');
841 check(ls, TOK_NUMBER);
842 eo_lexer_context_push(ls);
843 if (ls->t.kw == NUM_FLOAT || ls->t.kw == NUM_DOUBLE)
844 {
845 eo_lexer_context_restore(ls);
846 eo_lexer_syntax_error(ls, "integer expected");
847 }
848 eo_lexer_context_pop(ls);
849 switch (ls->t.kw)
850 {
851 case NUM_INT : def->static_size = ls->t.value.i; break;
852 case NUM_UINT : def->static_size = ls->t.value.u; break;
853 case NUM_LONG : def->static_size = ls->t.value.l; break;
854 case NUM_ULONG : def->static_size = ls->t.value.ul; break;
855 case NUM_LLONG : def->static_size = ls->t.value.ll; break;
856 case NUM_ULLONG: def->static_size = ls->t.value.ull; break;
857 default:
858 eo_lexer_syntax_error(ls, "wrong type, internal error");
859 break;
860 }
861 eo_lexer_get(ls);
862 check_next(ls, '>');
863 }
864 else if (ls->t.kw == KW_terminated_array)
865 {
866 def->type = EOLIAN_TYPE_TERMINATED_ARRAY;
867 eo_lexer_get(ls);
868 check_next(ls, '<');
869 eo_lexer_context_push(ls);
870 def->base_type = parse_type(ls, EINA_FALSE, EINA_FALSE);
871 if (!_type_is_terminatable(def->base_type))
872 {
873 eo_lexer_context_restore(ls);
874 eo_lexer_syntax_error(ls, "terminatable type expected");
875 }
876 eo_lexer_context_pop(ls);
877 pop_type(ls);
878 check_next(ls, '>');
879 }
806 else 880 else
807 { 881 {
808 int tpid = ls->t.kw; 882 int tpid = ls->t.kw;
809 def->type = EOLIAN_TYPE_REGULAR; 883 def->type = EOLIAN_TYPE_REGULAR;
810 check(ls, TOK_VALUE); 884 check(ls, TOK_VALUE);
811 if (eo_lexer_get_c_type(ls->t.kw)) 885 if (eo_lexer_is_type_keyword(ls->t.kw))
812 { 886 {
813 _fill_name(eina_stringshare_ref(ls->t.value.s), &def->full_name, 887 _fill_name(eina_stringshare_ref(ls->t.value.s), &def->full_name,
814 &def->name, &def->namespaces); 888 &def->name, &def->namespaces);
@@ -818,17 +892,17 @@ parse_type_void(Eo_Lexer *ls, Eina_Bool allow_ref)
818 int bline = ls->line_number, bcol = ls->column; 892 int bline = ls->line_number, bcol = ls->column;
819 def->type = EOLIAN_TYPE_COMPLEX; 893 def->type = EOLIAN_TYPE_COMPLEX;
820 check_next(ls, '<'); 894 check_next(ls, '<');
821 def->base_type = parse_type(ls, EINA_FALSE); 895 def->base_type = parse_type(ls, EINA_FALSE, EINA_FALSE);
822 pop_type(ls); 896 pop_type(ls);
823 if (tpid == KW_hash) 897 if (tpid == KW_hash)
824 { 898 {
825 check_next(ls, ','); 899 check_next(ls, ',');
826 def->base_type->next_type = parse_type(ls, EINA_FALSE); 900 def->base_type->next_type = parse_type(ls, EINA_FALSE, EINA_FALSE);
827 pop_type(ls); 901 pop_type(ls);
828 } 902 }
829 else if(tpid == KW_promise && test_next(ls, ',')) 903 else if(tpid == KW_promise && test_next(ls, ','))
830 { 904 {
831 def->base_type->next_type = parse_type(ls, EINA_FALSE); 905 def->base_type->next_type = parse_type(ls, EINA_FALSE, EINA_FALSE);
832 pop_type(ls); 906 pop_type(ls);
833 } 907 }
834 check_match(ls, '>', '<', bline, bcol); 908 check_match(ls, '>', '<', bline, bcol);
@@ -920,7 +994,7 @@ parse_typedef(Eo_Lexer *ls)
920 } 994 }
921 eo_lexer_context_pop(ls); 995 eo_lexer_context_pop(ls);
922 check_next(ls, ':'); 996 check_next(ls, ':');
923 def->base_type = parse_type(ls, EINA_FALSE); 997 def->base_type = parse_type(ls, EINA_FALSE, EINA_FALSE);
924 pop_type(ls); 998 pop_type(ls);
925 check_next(ls, ';'); 999 check_next(ls, ';');
926 FILL_DOC(ls, def, doc); 1000 FILL_DOC(ls, def, doc);
@@ -959,7 +1033,7 @@ parse_variable(Eo_Lexer *ls, Eina_Bool global)
959 } 1033 }
960 eo_lexer_context_pop(ls); 1034 eo_lexer_context_pop(ls);
961 check_next(ls, ':'); 1035 check_next(ls, ':');
962 def->base_type = parse_type(ls, EINA_FALSE); 1036 def->base_type = parse_type(ls, EINA_FALSE, EINA_FALSE);
963 pop_type(ls); 1037 pop_type(ls);
964 if ((ls->t.token == '=') && !has_extern) 1038 if ((ls->t.token == '=') && !has_extern)
965 { 1039 {
@@ -988,9 +1062,9 @@ parse_return(Eo_Lexer *ls, Eo_Ret_Def *ret, Eina_Bool allow_void)
988 eo_lexer_get(ls); 1062 eo_lexer_get(ls);
989 check_next(ls, ':'); 1063 check_next(ls, ':');
990 if (allow_void) 1064 if (allow_void)
991 ret->type = parse_type_void(ls, EINA_TRUE); 1065 ret->type = parse_type_void(ls, EINA_TRUE, EINA_FALSE);
992 else 1066 else
993 ret->type = parse_type(ls, EINA_TRUE); 1067 ret->type = parse_type(ls, EINA_TRUE, EINA_FALSE);
994 ret->doc = NULL; 1068 ret->doc = NULL;
995 ret->default_ret_val = NULL; 1069 ret->default_ret_val = NULL;
996 ret->warn_unused = EINA_FALSE; 1070 ret->warn_unused = EINA_FALSE;
@@ -1049,9 +1123,9 @@ parse_param(Eo_Lexer *ls, Eina_List **params, Eina_Bool allow_inout,
1049 eo_lexer_get(ls); 1123 eo_lexer_get(ls);
1050 check_next(ls, ':'); 1124 check_next(ls, ':');
1051 if (par->param_dir == EOLIAN_OUT_PARAM || par->param_dir == EOLIAN_INOUT_PARAM) 1125 if (par->param_dir == EOLIAN_OUT_PARAM || par->param_dir == EOLIAN_INOUT_PARAM)
1052 par->type = parse_type_void(ls, EINA_TRUE); 1126 par->type = parse_type_void(ls, EINA_TRUE, EINA_FALSE);
1053 else 1127 else
1054 par->type = parse_type(ls, EINA_TRUE); 1128 par->type = parse_type(ls, EINA_TRUE, EINA_FALSE);
1055 pop_type(ls); 1129 pop_type(ls);
1056 if ((is_vals || (par->param_dir == EOLIAN_OUT_PARAM)) && (ls->t.token == '(')) 1130 if ((is_vals || (par->param_dir == EOLIAN_OUT_PARAM)) && (ls->t.token == '('))
1057 { 1131 {
@@ -1649,7 +1723,7 @@ end:
1649 if (ls->t.token == ':') 1723 if (ls->t.token == ':')
1650 { 1724 {
1651 eo_lexer_get(ls); 1725 eo_lexer_get(ls);
1652 ev->type = parse_type(ls, EINA_TRUE); 1726 ev->type = parse_type(ls, EINA_TRUE, EINA_FALSE);
1653 pop_type(ls); 1727 pop_type(ls);
1654 } 1728 }
1655 check(ls, ';'); 1729 check(ls, ';');
diff --git a/src/lib/eolian/eolian_database.h b/src/lib/eolian/eolian_database.h
index 874862b..9becd5a 100644
--- a/src/lib/eolian/eolian_database.h
+++ b/src/lib/eolian/eolian_database.h
@@ -173,6 +173,7 @@ struct _Eolian_Type
173 Eina_Stringshare *full_name; 173 Eina_Stringshare *full_name;
174 Eina_List *namespaces; 174 Eina_List *namespaces;
175 Eina_Stringshare *freefunc; 175 Eina_Stringshare *freefunc;
176 size_t static_size;
176 Eina_Bool is_const :1; 177 Eina_Bool is_const :1;
177 Eina_Bool is_own :1; 178 Eina_Bool is_own :1;
178 Eina_Bool is_ref :1; 179 Eina_Bool is_ref :1;
diff --git a/src/tests/eolian/data/struct.eo b/src/tests/eolian/data/struct.eo
index 077e499..81429b9 100644
--- a/src/tests/eolian/data/struct.eo
+++ b/src/tests/eolian/data/struct.eo
@@ -1,6 +1,8 @@
1struct Named { 1struct Named {
2 field: ref(int); 2 field: ref(int);
3 something: string; 3 something: string;
4 arr: static_array<int, 16>;
5 tarr: terminated_array<string>;
4} 6}
5 7
6struct Another { 8struct Another {
diff --git a/src/tests/eolian/data/struct_ref.c b/src/tests/eolian/data/struct_ref.c
index 1fbec77..dd9c64e 100644
--- a/src/tests/eolian/data/struct_ref.c
+++ b/src/tests/eolian/data/struct_ref.c
@@ -15,6 +15,8 @@ typedef struct _Named
15{ 15{
16 int *field; 16 int *field;
17 const char *something; 17 const char *something;
18 int arr[16];
19 const char **tarr;
18} Named; 20} Named;
19 21
20typedef struct _Another 22typedef struct _Another
diff --git a/src/tests/eolian/eolian_parsing.c b/src/tests/eolian/eolian_parsing.c
index 6078493..2a880da 100644
--- a/src/tests/eolian/eolian_parsing.c
+++ b/src/tests/eolian/eolian_parsing.c
@@ -692,6 +692,21 @@ START_TEST(eolian_struct)
692 fail_if(!(type_name = eolian_type_c_type_get(ftype))); 692 fail_if(!(type_name = eolian_type_c_type_get(ftype)));
693 fail_if(strcmp(type_name, "const char *")); 693 fail_if(strcmp(type_name, "const char *"));
694 eina_stringshare_del(type_name); 694 eina_stringshare_del(type_name);
695 fail_if(!(field = eolian_typedecl_struct_field_get(tdl, "arr")));
696 fail_if(!(ftype = eolian_typedecl_struct_field_type_get(field)));
697 fail_if(eolian_type_is_ref(ftype));
698 fail_if(eolian_type_array_size_get(ftype) != 16);
699 fail_if(eolian_type_type_get(ftype) != EOLIAN_TYPE_STATIC_ARRAY);
700 fail_if(!(type_name = eolian_type_c_type_get(ftype)));
701 fail_if(strcmp(type_name, "int *"));
702 eina_stringshare_del(type_name);
703 fail_if(!(field = eolian_typedecl_struct_field_get(tdl, "tarr")));
704 fail_if(!(ftype = eolian_typedecl_struct_field_type_get(field)));
705 fail_if(eolian_type_is_ref(ftype));
706 fail_if(!(type_name = eolian_type_c_type_get(ftype)));
707 fail_if(eolian_type_type_get(ftype) != EOLIAN_TYPE_TERMINATED_ARRAY);
708 fail_if(strcmp(type_name, "const char **"));
709 eina_stringshare_del(type_name);
695 710
696 /* referencing */ 711 /* referencing */
697 fail_if(!(tdl = eolian_typedecl_struct_get_by_name("Another"))); 712 fail_if(!(tdl = eolian_typedecl_struct_get_by_name("Another")));