summaryrefslogtreecommitdiff
path: root/src/bin/eolian
diff options
context:
space:
mode:
authorDaniel Zaoui <daniel.zaoui@samsung.com>2014-09-04 13:22:31 +0300
committerDaniel Zaoui <daniel.zaoui@samsung.com>2014-09-08 10:11:01 +0300
commit56bad2beb0e9c5606987eb91a1a6f4f71d3052a2 (patch)
tree280f44746ba9fa5b2cffe65fd5dad6b1de335ff6 /src/bin/eolian
parentf7483040796cda16205ad40a35665ecd1217c148 (diff)
Eolian/Generator: support @empty and @auto.
Local and base class functions are supported. When @empty is provided, dummy functions (initializing the parameters with default values if needed) are generated. When @auto is provided on properties, access to internal data variables is done. On set, it will assign parameters values to private data members. On get, parameters are set with private data members values. See the supplied tests as examples. @feature
Diffstat (limited to 'src/bin/eolian')
-rw-r--r--src/bin/eolian/eo_generator.c158
1 files changed, 109 insertions, 49 deletions
diff --git a/src/bin/eolian/eo_generator.c b/src/bin/eolian/eo_generator.c
index 0a292f08aa..56e40ab010 100644
--- a/src/bin/eolian/eo_generator.c
+++ b/src/bin/eolian/eo_generator.c
@@ -339,7 +339,7 @@ eo_header_generate(const Eolian_Class *class, Eina_Strbuf *buf)
339} 339}
340 340
341static Eina_Bool 341static Eina_Bool
342eo_bind_func_generate(const Eolian_Class *class, const Eolian_Function *funcid, Eolian_Function_Type ftype, Eina_Strbuf *buf, _eolian_class_vars *impl_env) 342eo_bind_func_generate(const Eolian_Class *class, const Eolian_Function *funcid, Eolian_Function_Type ftype, Eina_Strbuf *buf, Eolian_Implement *impl, _eolian_class_vars *impl_env)
343{ 343{
344 _eolian_class_func_vars func_env; 344 _eolian_class_func_vars func_env;
345 const char *suffix = ""; 345 const char *suffix = "";
@@ -351,6 +351,9 @@ eo_bind_func_generate(const Eolian_Class *class, const Eolian_Function *funcid,
351 Eina_Iterator *itr; 351 Eina_Iterator *itr;
352 void *data, *data2; 352 void *data, *data2;
353 const Eolian_Expression *default_ret_val = NULL; 353 const Eolian_Expression *default_ret_val = NULL;
354 Eina_Bool is_empty = impl ? eolian_implement_is_empty(impl) : eolian_function_is_empty(funcid, ftype);
355 Eina_Bool is_auto = impl ? eolian_implement_is_auto(impl) : eolian_function_is_auto(funcid, ftype);
356 if (ftype != EOLIAN_PROP_GET && ftype != EOLIAN_PROP_SET) ftype = eolian_function_type_get(funcid);
354 357
355 Eina_Bool need_implementation = EINA_TRUE; 358 Eina_Bool need_implementation = EINA_TRUE;
356 if (!impl_env && eolian_function_is_virtual_pure(funcid, ftype)) need_implementation = EINA_FALSE; 359 if (!impl_env && eolian_function_is_virtual_pure(funcid, ftype)) need_implementation = EINA_FALSE;
@@ -363,7 +366,10 @@ eo_bind_func_generate(const Eolian_Class *class, const Eolian_Function *funcid,
363 366
364 rettypet = eolian_function_return_type_get(funcid, ftype); 367 rettypet = eolian_function_return_type_get(funcid, ftype);
365 if (rettypet) 368 if (rettypet)
366 default_ret_val = eolian_function_return_default_value_get(funcid, ftype); 369 {
370 is_auto = EINA_FALSE; /* We block auto when the function has to return something */
371 default_ret_val = eolian_function_return_default_value_get(funcid, ftype);
372 }
367 if (ftype == EOLIAN_PROP_GET) 373 if (ftype == EOLIAN_PROP_GET)
368 { 374 {
369 suffix = "_get"; 375 suffix = "_get";
@@ -398,9 +404,9 @@ eo_bind_func_generate(const Eolian_Class *class, const Eolian_Function *funcid,
398 Eina_Bool is_const = eolian_parameter_const_attribute_get(data, ftype == EOLIAN_PROP_GET); 404 Eina_Bool is_const = eolian_parameter_const_attribute_get(data, ftype == EOLIAN_PROP_GET);
399 if (eina_strbuf_length_get(params)) eina_strbuf_append(params, ", "); 405 if (eina_strbuf_length_get(params)) eina_strbuf_append(params, ", ");
400 eina_strbuf_append_printf(params, "%s", pname); 406 eina_strbuf_append_printf(params, "%s", pname);
401 eina_strbuf_append_printf(full_params, ", %s%s %s", 407 eina_strbuf_append_printf(full_params, ", %s%s %s%s",
402 is_const?"const ":"", 408 is_const?"const ":"",
403 ptype, pname); 409 ptype, pname, is_empty || is_auto?" EINA_UNUSED":"");
404 eina_stringshare_del(ptype); 410 eina_stringshare_del(ptype);
405 } 411 }
406 eina_iterator_free(itr); 412 eina_iterator_free(itr);
@@ -410,6 +416,7 @@ eo_bind_func_generate(const Eolian_Class *class, const Eolian_Function *funcid,
410 EINA_ITERATOR_FOREACH(itr, data) 416 EINA_ITERATOR_FOREACH(itr, data)
411 { 417 {
412 Eolian_Function_Parameter *param = data; 418 Eolian_Function_Parameter *param = data;
419 const Eolian_Expression *dflt_value = eolian_parameter_default_value_get(param);
413 const Eolian_Type *ptypet = eolian_parameter_type_get(param); 420 const Eolian_Type *ptypet = eolian_parameter_type_get(param);
414 const char *pname = eolian_parameter_name_get(param); 421 const char *pname = eolian_parameter_name_get(param);
415 const char *ptype = eolian_type_c_type_get(ptypet); 422 const char *ptype = eolian_type_c_type_get(ptypet);
@@ -419,30 +426,44 @@ eo_bind_func_generate(const Eolian_Class *class, const Eolian_Function *funcid,
419 if (ftype == EOLIAN_UNRESOLVED || ftype == EOLIAN_METHOD) add_star = (pdir == EOLIAN_OUT_PARAM || pdir == EOLIAN_INOUT_PARAM); 426 if (ftype == EOLIAN_UNRESOLVED || ftype == EOLIAN_METHOD) add_star = (pdir == EOLIAN_OUT_PARAM || pdir == EOLIAN_INOUT_PARAM);
420 if (eina_strbuf_length_get(params)) eina_strbuf_append(params, ", "); 427 if (eina_strbuf_length_get(params)) eina_strbuf_append(params, ", ");
421 eina_strbuf_append_printf(params, "%s", pname); 428 eina_strbuf_append_printf(params, "%s", pname);
422 eina_strbuf_append_printf(full_params, ", %s%s%s%s%s", 429 eina_strbuf_append_printf(full_params, ", %s%s%s%s%s%s",
423 is_const?"const ":"", 430 is_const?"const ":"",
424 ptype, had_star?"":" ", add_star?"*":"", pname); 431 ptype, had_star?"":" ", add_star?"*":"", pname, is_empty && !dflt_value ?" EINA_UNUSED":"");
425 if (ftype != EOLIAN_PROP_SET) 432 if (is_auto)
426 { 433 {
427 const Eolian_Expression *dflt_value = eolian_parameter_default_value_get(param); 434 if (ftype == EOLIAN_PROP_SET)
428 if (dflt_value)
429 { 435 {
430 const char *val_str = NULL; 436 eina_strbuf_append_printf(params_init,
431 Eolian_Value val = eolian_expression_eval 437 " %s = pd->%s;\n", pname, pname);
432 (dflt_value, EOLIAN_MASK_ALL); 438 }
433 if (val.type) 439 else
440 {
441 eina_strbuf_append_printf(params_init,
442 " if (%s) *%s = pd->%s;\n", pname, pname, pname);
443 }
444 }
445 else {
446 if (ftype != EOLIAN_PROP_SET)
447 {
448 if (dflt_value)
434 { 449 {
435 val_str = eolian_expression_value_to_literal(&val); 450 const char *val_str = NULL;
436 eina_strbuf_append_printf(params_init, 451 Eolian_Value val = eolian_expression_eval
437 " if (%s) *%s = %s;", 452 (dflt_value, EOLIAN_MASK_ALL);
438 pname, pname, val_str); 453 if (val.type)
439 if (eolian_expression_type_get(dflt_value) == EOLIAN_EXPR_ENUM)
440 { 454 {
441 Eina_Stringshare *string = eolian_expression_serialize(dflt_value); 455 val_str = eolian_expression_value_to_literal(&val);
442 eina_strbuf_append_printf(params_init, " /* %s */", string); 456 eina_strbuf_append_printf(params_init,
443 eina_stringshare_del(string); 457 " if (%s) *%s = %s;",
458 pname, pname, val_str);
459 if (eolian_expression_type_get(dflt_value) == EOLIAN_EXPR_ENUM)
460 {
461 Eina_Stringshare *string = eolian_expression_serialize(dflt_value);
462 eina_strbuf_append_printf(params_init, " /* %s */", string);
463 eina_stringshare_del(string);
464 }
465 eina_strbuf_append_printf(params_init, "\n");
444 } 466 }
445 eina_strbuf_append_printf(params_init, "\n");
446 } 467 }
447 } 468 }
448 } 469 }
@@ -457,25 +478,59 @@ eo_bind_func_generate(const Eolian_Class *class, const Eolian_Function *funcid,
457 { 478 {
458 Eina_Strbuf *ret_param = eina_strbuf_new(); 479 Eina_Strbuf *ret_param = eina_strbuf_new();
459 eina_strbuf_append_printf(fbody, "\n"); 480 eina_strbuf_append_printf(fbody, "\n");
460 eina_strbuf_append_printf(fbody, "%s%s _%s%s%s_%s%s(Eo *obj, @#Datatype_Data *pd@#full_params);\n\n", 481 /* Generation of the user function prototype declaration - not needed when @auto and @empty are indicated */
461 ret_const?"const ":"", rettype?rettype:"void", 482 if (!is_empty && !is_auto)
462 class_env.lower_classname, 483 {
463 impl_env?"_":"", 484 eina_strbuf_append_printf(fbody, "%s%s _%s%s%s_%s%s(Eo *obj, @#Datatype_Data *pd%s);\n\n",
464 impl_env?impl_env->lower_classname:"", 485 ret_const?"const ":"", rettype?rettype:"void",
465 eolian_function_name_get(funcid), suffix); 486 class_env.lower_classname,
487 impl_env?"_":"",
488 impl_env?impl_env->lower_classname:"",
489 eolian_function_name_get(funcid), suffix,
490 eina_strbuf_string_get(full_params));
491 }
466 492
467 if (eina_strbuf_length_get(params_init)) 493 if (is_empty || is_auto || eina_strbuf_length_get(params_init))
468 { 494 {
495 /* We need to give the internal function name to Eo. We use this hash table as indication */
469 eina_hash_add(_funcs_params_init, 496 eina_hash_add(_funcs_params_init,
470 eina_stringshare_add(eolian_function_name_get(funcid)), funcid); 497 eina_stringshare_add(eolian_function_name_get(funcid)), (void *)ftype);
471 eina_strbuf_append_printf(fbody, "static %s%s __eolian_%s%s%s_%s%s(Eo *obj, @#Datatype_Data *pd@#full_params)\n{\n%s\n", 498 /* Generation of the intermediate function __eolian_... */
499 eina_strbuf_append_printf(fbody, "static %s%s __eolian_%s%s%s_%s%s(Eo *obj%s, @#Datatype_Data *pd%s%s)\n{\n",
472 ret_const?"const ":"", rettype?rettype:"void", 500 ret_const?"const ":"", rettype?rettype:"void",
473 class_env.lower_classname, 501 class_env.lower_classname,
474 impl_env?"_":"", 502 impl_env?"_":"",
475 impl_env?impl_env->lower_classname:"", 503 impl_env?impl_env->lower_classname:"",
476 eolian_function_name_get(funcid), suffix, 504 eolian_function_name_get(funcid), suffix,
477 eina_strbuf_string_get(params_init)); 505 is_empty || is_auto?" EINA_UNUSED":"",
478 eina_strbuf_append_printf(fbody, " %s_%s%s%s_%s%s(obj, pd, %s);\n}\n\n", 506 is_empty || (is_auto && !eina_strbuf_length_get(params_init))?" EINA_UNUSED":"",
507 eina_strbuf_string_get(full_params));
508 }
509 if (eina_strbuf_length_get(params_init))
510 {
511 eina_strbuf_append_printf(fbody, "%s", eina_strbuf_string_get(params_init));
512 }
513 if (is_auto || is_empty)
514 {
515 if (rettype)
516 {
517 /* return for auto and empty */
518 const char *val_str = NULL;
519 if (default_ret_val)
520 {
521 Eolian_Value val = eolian_expression_eval
522 (default_ret_val, EOLIAN_MASK_ALL);
523 if (val.type)
524 val_str = eolian_expression_value_to_literal(&val);
525 }
526 eina_strbuf_append_printf(fbody, " return %s;\n", val_str?val_str:"0");
527 }
528 eina_strbuf_append_printf(fbody, "}\n\n");
529 }
530 else if (eina_strbuf_length_get(params_init))
531 {
532 /* Generation of the user function invocation, e.g return _user_foo(obj, pd, ...) */
533 eina_strbuf_append_printf(fbody, " %s_%s%s%s_%s%s(obj, pd, %s);\n}\n\n",
479 rettype?"return ":"", 534 rettype?"return ":"",
480 class_env.lower_classname, 535 class_env.lower_classname,
481 impl_env?"_":"", 536 impl_env?"_":"",
@@ -528,6 +583,7 @@ eo_bind_func_generate(const Eolian_Class *class, const Eolian_Function *funcid,
528 } 583 }
529 if (has_params) 584 if (has_params)
530 { 585 {
586 eina_strbuf_replace_all(full_params, " EINA_UNUSED", "");
531 eina_strbuf_append_printf(eo_func_decl, ", EO_FUNC_CALL(%s)%s", 587 eina_strbuf_append_printf(eo_func_decl, ", EO_FUNC_CALL(%s)%s",
532 eina_strbuf_string_get(params), 588 eina_strbuf_string_get(params),
533 eina_strbuf_string_get(full_params)); 589 eina_strbuf_string_get(full_params));
@@ -540,7 +596,6 @@ eo_bind_func_generate(const Eolian_Class *class, const Eolian_Function *funcid,
540 if (need_implementation) 596 if (need_implementation)
541 { 597 {
542 Eina_Bool is_cf = eolian_function_is_class(funcid); 598 Eina_Bool is_cf = eolian_function_is_class(funcid);
543 eina_strbuf_replace_all(fbody, "@#full_params", eina_strbuf_string_get(full_params));
544 const char *data_type = eolian_class_data_type_get(class); 599 const char *data_type = eolian_class_data_type_get(class);
545 if (is_cf || (data_type && !strcmp(data_type, "null"))) 600 if (is_cf || (data_type && !strcmp(data_type, "null")))
546 eina_strbuf_replace_all(fbody, "@#Datatype_Data", "void"); 601 eina_strbuf_replace_all(fbody, "@#Datatype_Data", "void");
@@ -585,9 +640,9 @@ eo_op_desc_generate(const Eolian_Class *class, const Eolian_Function *fid, Eolia
585 eina_strbuf_append_printf(buf, "\n EO_OP_%sFUNC(%s, ", class_str, func_env.lower_eo_func); 640 eina_strbuf_append_printf(buf, "\n EO_OP_%sFUNC(%s, ", class_str, func_env.lower_eo_func);
586 if (!is_virtual_pure) 641 if (!is_virtual_pure)
587 { 642 {
643 Eolian_Function_Type ftype2 = (Eolian_Function_Type) eina_hash_find(_funcs_params_init, funcname);
588 eina_strbuf_append_printf(buf, "%s_%s_%s%s, \"%s\"),", 644 eina_strbuf_append_printf(buf, "%s_%s_%s%s, \"%s\"),",
589 eina_hash_find(_funcs_params_init, funcname) 645 ftype == ftype2?"__eolian":"",
590 && ftype != EOLIAN_PROP_SET?"__eolian":"",
591 class_env.lower_classname, funcname, suffix, desc); 646 class_env.lower_classname, funcname, suffix, desc);
592 } 647 }
593 else 648 else
@@ -731,19 +786,24 @@ eo_source_end_generate(const Eolian_Class *class, Eina_Strbuf *buf)
731 const Eolian_Function *fnid = NULL; 786 const Eolian_Function *fnid = NULL;
732 const char *funcname = NULL; 787 const char *funcname = NULL;
733 const char *rets; 788 const char *rets;
734 char *tp = implname;
735 789
736 const char *names[] = { "", "getter ", "setter " }; 790 const char *names[] = { "", "getter ", "setter " };
737 791
738 if ((impl_class = eolian_implement_class_get(impl_desc))) 792 impl_class = eolian_implement_class_get(impl_desc);
793
794 if (impl_class)
739 { 795 {
796 char *tp = implname;
740 if (impl_class == class) 797 if (impl_class == class)
741 continue; 798 continue;
742 fnid = eolian_implement_function_get(impl_desc, &ftype); 799 fnid = eolian_implement_function_get(impl_desc, &ftype);
743 _class_env_create(impl_class, NULL, &impl_env); 800 _class_env_create(impl_class, NULL, &impl_env);
744 funcname = eolian_function_name_get(fnid); 801 funcname = eolian_function_name_get(fnid);
745 802
746 sprintf(implname, "%s_%s", class_env.full_classname, impl_env.full_classname); 803 sprintf(implname, "%s_%s_%s",
804 eolian_implement_is_auto(impl_desc) || eolian_implement_is_empty(impl_desc)?
805 "__eolian":"",
806 class_env.full_classname, impl_env.full_classname);
747 eina_str_tolower(&tp); 807 eina_str_tolower(&tp);
748 } 808 }
749 809
@@ -766,22 +826,22 @@ eo_source_end_generate(const Eolian_Class *class, Eina_Strbuf *buf)
766 case EOLIAN_PROP_SET: case EOLIAN_PROP_GET: case EOLIAN_PROPERTY: 826 case EOLIAN_PROP_SET: case EOLIAN_PROP_GET: case EOLIAN_PROPERTY:
767 if (ftype != EOLIAN_PROP_GET) 827 if (ftype != EOLIAN_PROP_GET)
768 { 828 {
769 eina_strbuf_append_printf(str_op, "\n EO_OP_%sFUNC_OVERRIDE(%s_set, _%s_%s_set),", 829 eina_strbuf_append_printf(str_op, "\n EO_OP_%sFUNC_OVERRIDE(%s_set, %s_%s_set),",
770 class_str, rets, implname, funcname); 830 class_str, rets, implname, funcname);
771 eo_bind_func_generate(class, fnid, EOLIAN_PROP_SET, str_bodyf, &impl_env); 831 eo_bind_func_generate(class, fnid, EOLIAN_PROP_SET, str_bodyf, impl_desc, &impl_env);
772 } 832 }
773 833
774 if (ftype != EOLIAN_PROP_SET) 834 if (ftype != EOLIAN_PROP_SET)
775 { 835 {
776 eina_strbuf_append_printf(str_op, "\n EO_OP_%sFUNC_OVERRIDE(%s_get, _%s_%s_get),", 836 eina_strbuf_append_printf(str_op, "\n EO_OP_%sFUNC_OVERRIDE(%s_get, %s_%s_get),",
777 class_str, rets, implname, funcname); 837 class_str, rets, implname, funcname);
778 eo_bind_func_generate(class, fnid, EOLIAN_PROP_GET, str_bodyf, &impl_env); 838 eo_bind_func_generate(class, fnid, EOLIAN_PROP_GET, str_bodyf, impl_desc, &impl_env);
779 } 839 }
780 break; 840 break;
781 default: 841 default:
782 eina_strbuf_append_printf(str_op, "\n EO_OP_%sFUNC_OVERRIDE(%s, _%s_%s),", 842 eina_strbuf_append_printf(str_op, "\n EO_OP_%sFUNC_OVERRIDE(%s, %s_%s),",
783 class_str, rets, implname, funcname); 843 class_str, rets, implname, funcname);
784 eo_bind_func_generate(class, fnid, ftype, str_bodyf, &impl_env); 844 eo_bind_func_generate(class, fnid, ftype, str_bodyf, impl_desc, &impl_env);
785 break; 845 break;
786 } 846 }
787 eina_stringshare_del(rets); 847 eina_stringshare_del(rets);
@@ -929,17 +989,17 @@ eo_source_generate(const Eolian_Class *class, Eina_Strbuf *buf)
929 switch (ftype) 989 switch (ftype)
930 { 990 {
931 case EOLIAN_PROP_GET: case EOLIAN_PROP_SET: 991 case EOLIAN_PROP_GET: case EOLIAN_PROP_SET:
932 if (!eo_bind_func_generate(class, fid, ftype, str_bodyf, NULL)) 992 if (!eo_bind_func_generate(class, fid, ftype, str_bodyf, NULL, NULL))
933 goto end; 993 goto end;
934 break; 994 break;
935 case EOLIAN_PROPERTY: 995 case EOLIAN_PROPERTY:
936 if (!eo_bind_func_generate(class, fid, EOLIAN_PROP_SET, str_bodyf, NULL)) 996 if (!eo_bind_func_generate(class, fid, EOLIAN_PROP_SET, str_bodyf, NULL, NULL))
937 goto end; 997 goto end;
938 if (!eo_bind_func_generate(class, fid, EOLIAN_PROP_GET, str_bodyf, NULL)) 998 if (!eo_bind_func_generate(class, fid, EOLIAN_PROP_GET, str_bodyf, NULL, NULL))
939 goto end; 999 goto end;
940 break; 1000 break;
941 default: 1001 default:
942 if (!eo_bind_func_generate(class, fid, EOLIAN_UNRESOLVED, str_bodyf, NULL)) 1002 if (!eo_bind_func_generate(class, fid, EOLIAN_UNRESOLVED, str_bodyf, NULL, NULL))
943 goto end; 1003 goto end;
944 break; 1004 break;
945 } 1005 }