eolian: test for constants/globals
authorDaniel Kolesa <d.kolesa@samsung.com>
Fri, 8 Aug 2014 15:28:31 +0000 (16:28 +0100)
committerDaniel Kolesa <d.kolesa@samsung.com>
Thu, 21 Aug 2014 08:26:04 +0000 (09:26 +0100)
Also added API to retrieve value of a variable (forgot about that one)
and made it impossible to create extern constants (doesn't make sense)
as well as made it impossible to give extern globals values.

src/Makefile_Eolian.am
src/lib/eolian/Eolian.h
src/lib/eolian/database_var_api.c
src/lib/eolian/eo_parser.c
src/tests/eolian/data/var.eo [new file with mode: 0644]
src/tests/eolian/eolian_parsing.c

index 767cc76..1d3a647 100644 (file)
@@ -109,6 +109,7 @@ tests/eolian/data/events.eo \
 tests/eolian/data/namespace.eo \
 tests/eolian/data/extern.eo \
 tests/eolian/data/struct.eo \
+tests/eolian/data/var.eo \
 tests/eolian/data/class_funcs.eo \
 tests/eolian/data/typedef_ref.c \
 tests/eolian/data/struct_ref.c
index 506c4e6..5bf7fbb 100644 (file)
@@ -1226,6 +1226,16 @@ EAPI Eina_Stringshare *eolian_variable_file_get(const Eolian_Variable *var);
 EAPI const Eolian_Type *eolian_variable_base_type_get(const Eolian_Variable *var);
 
 /*
+ * @brief Get the value of a variable.
+ *
+ * @param[in] var the variable.
+ * @return the value or NULL.
+ *
+ * @ingroup Eolian
+ */
+EAPI const Eolian_Expression *eolian_variable_value_get(const Eolian_Variable *var);
+
+/*
  * @brief Get the name of the given variable (without namespaces).
  *
  * @param[in] var the variable.
index 6cf6664..19affd2 100644 (file)
@@ -72,6 +72,13 @@ eolian_variable_base_type_get(const Eolian_Variable *var)
    return var->base_type;
 }
 
+EAPI const Eolian_Expression *
+eolian_variable_value_get(const Eolian_Variable *var)
+{
+   EINA_SAFETY_ON_NULL_RETURN_VAL(var, NULL);
+   return var->value;
+}
+
 EAPI Eina_Stringshare *
 eolian_variable_name_get(const Eolian_Variable *var)
 {
index e9e1ab1..46ffd6b 100644 (file)
@@ -841,6 +841,8 @@ parse_variable(Eo_Lexer *ls, Eina_Bool global)
    eo_lexer_get(ls);
    if (ls->t.kw == KW_at_extern)
      {
+        if (!global)
+          eo_lexer_syntax_error(ls, "extern constant");
         is_extern = EINA_TRUE;
         eo_lexer_get(ls);
      }
@@ -856,7 +858,7 @@ parse_variable(Eo_Lexer *ls, Eina_Bool global)
    check_next(ls, ':');
    def->base_type = parse_type(ls);
    pop_type(ls);
-   if (ls->t.token == '=')
+   if ((ls->t.token == '=') && !is_extern)
      {
         ls->expr_mode = EINA_TRUE;
         eo_lexer_get(ls);
diff --git a/src/tests/eolian/data/var.eo b/src/tests/eolian/data/var.eo
new file mode 100644 (file)
index 0000000..cdc624e
--- /dev/null
@@ -0,0 +1,22 @@
+// regular constant
+const Foo: int = 5;
+
+// regular global
+var Bar: float = 10.3f;
+
+// no-value global
+var Baz: long;
+
+// extern global
+var @extern Bah: double;
+
+class Var {
+   methods {
+      foo {
+         params {
+            int idx;
+         }
+         return: own(char*);
+      }
+   }
+}
index 8f2a1fd..9cdfaea 100644 (file)
@@ -649,6 +649,76 @@ START_TEST(eolian_extern)
 }
 END_TEST
 
+START_TEST(eolian_var)
+{
+   const Eolian_Variable *var = NULL;
+   const Eolian_Expression *exp = NULL;
+   const Eolian_Type *type = NULL;
+   const Eolian_Class *class;
+   const char *name;
+   Eina_Value *v = NULL;
+   int i = 0;
+   float f = 0.0f;
+
+   eolian_init();
+
+   /* Parsing */
+   fail_if(!eolian_eo_file_parse(PACKAGE_DATA_DIR"/data/var.eo"));
+
+   /* Check that the class Dummy is still readable */
+   fail_if(!(class = eolian_class_get_by_name("Var")));
+   fail_if(!eolian_class_function_get_by_name(class, "foo", EOLIAN_METHOD));
+
+   /* regular constant */
+   fail_if(!(var = eolian_variable_constant_get_by_name("Foo")));
+   fail_if(eolian_variable_type_get(var) != EOLIAN_VAR_CONSTANT);
+   fail_if(eolian_variable_is_extern(var));
+   fail_if(!(type = eolian_variable_base_type_get(var)));
+   fail_if(!(name = eolian_type_name_get(type)));
+   fail_if(strcmp(name, "int"));
+   eina_stringshare_del(name);
+   fail_if(!(exp = eolian_variable_value_get(var)));
+   fail_if(eolian_expression_eval_type(exp, type, &v) != EOLIAN_EXPR_INT);
+   eina_value_get(v, &i);
+   fail_if(i != 5);
+
+   /* regular global */
+   fail_if(!(var = eolian_variable_global_get_by_name("Bar")));
+   fail_if(eolian_variable_type_get(var) != EOLIAN_VAR_GLOBAL);
+   fail_if(eolian_variable_is_extern(var));
+   fail_if(!(type = eolian_variable_base_type_get(var)));
+   fail_if(!(name = eolian_type_name_get(type)));
+   fail_if(strcmp(name, "float"));
+   eina_stringshare_del(name);
+   fail_if(!(exp = eolian_variable_value_get(var)));
+   fail_if(eolian_expression_eval_type(exp, type, &v) != EOLIAN_EXPR_FLOAT);
+   eina_value_get(v, &f);
+   fail_if(((int)f) != 10);
+
+   /* no-value global */
+   fail_if(!(var = eolian_variable_global_get_by_name("Baz")));
+   fail_if(eolian_variable_type_get(var) != EOLIAN_VAR_GLOBAL);
+   fail_if(eolian_variable_is_extern(var));
+   fail_if(!(type = eolian_variable_base_type_get(var)));
+   fail_if(!(name = eolian_type_name_get(type)));
+   fail_if(strcmp(name, "long"));
+   eina_stringshare_del(name);
+   fail_if(eolian_variable_value_get(var));
+
+   /* extern global  */
+   fail_if(!(var = eolian_variable_global_get_by_name("Bah")));
+   fail_if(eolian_variable_type_get(var) != EOLIAN_VAR_GLOBAL);
+   fail_if(!eolian_variable_is_extern(var));
+   fail_if(!(type = eolian_variable_base_type_get(var)));
+   fail_if(!(name = eolian_type_name_get(type)));
+   fail_if(strcmp(name, "double"));
+   eina_stringshare_del(name);
+   fail_if(eolian_variable_value_get(var));
+
+   eolian_shutdown();
+}
+END_TEST
+
 START_TEST(eolian_class_funcs)
 {
    const Eolian_Function *fid = NULL;
@@ -696,6 +766,7 @@ void eolian_parsing_test(TCase *tc)
    tcase_add_test(tc, eolian_namespaces);
    tcase_add_test(tc, eolian_struct);
    tcase_add_test(tc, eolian_extern);
+   tcase_add_test(tc, eolian_var);
    tcase_add_test(tc, eolian_class_funcs);
 }