2016-09-22 06:58:06 -07:00
# include "main.h"
# include "docs.h"
2016-09-23 08:49:44 -07:00
/* Used to store the function names that will have to be appended
* with __eolian during C generation . Needed when params have to
* be initialized and for future features .
*/
2016-12-27 08:16:17 -08:00
static Eina_Hash * _funcs_params_init_get = NULL ;
static Eina_Hash * _funcs_params_init_set = NULL ;
2016-09-23 08:49:44 -07:00
static const char *
_get_add_star ( Eolian_Function_Type ftype , Eolian_Parameter_Dir pdir )
{
if ( ftype = = EOLIAN_PROP_GET )
return " * " ;
if ( ( pdir = = EOLIAN_OUT_PARAM ) | | ( pdir = = EOLIAN_INOUT_PARAM ) )
return " * " ;
return " " ;
}
2016-10-05 07:32:17 -07:00
static Eina_Bool
_function_exists ( const char * fname , Eina_Strbuf * buf )
{
const char * ptr = eina_strbuf_string_get ( buf ) ;
size_t flen = strlen ( fname ) ;
while ( ( ptr = strstr ( ptr , fname ) ) ! = NULL )
{
switch ( * ( ptr - 1 ) )
{
case ' \n ' :
case ' ' :
switch ( * ( ptr + flen ) )
{
case ' ' :
case ' ( ' :
return EINA_TRUE ;
}
}
+ + ptr ;
}
return EINA_FALSE ;
}
/* Check if the type is used in the file, not if it is a typedef... */
static Eina_Bool
_type_exists ( const char * tname , Eina_Strbuf * buf )
{
const char * ptr = eina_strbuf_string_get ( buf ) ;
size_t tlen = strlen ( tname ) ;
while ( ( ptr = strstr ( ptr , tname ) ) ! = NULL )
{
switch ( * ( ptr - 1 ) )
{
case ' \n ' :
case ' ' :
case ' , ' :
switch ( * ( ptr + tlen ) )
{
case ' \n ' :
case ' ' :
case ' , ' :
case ' ; ' :
return EINA_TRUE ;
}
}
+ + ptr ;
}
return EINA_FALSE ;
}
2017-04-07 09:54:55 -07:00
static void
_gen_func_pointer_param ( const char * name , Eina_Stringshare * c_type ,
const Eolian_Typedecl * typedecl EINA_UNUSED ,
Eina_Strbuf * params , Eina_Strbuf * params_full ,
Eina_Strbuf * params_full_imp ,
Eina_Bool is_empty EINA_UNUSED )
{
Eina_Strbuf * dataname = eina_strbuf_new ( ) ;
Eina_Strbuf * freename = eina_strbuf_new ( ) ;
eina_strbuf_append_printf ( dataname , " %s_data " , name ) ;
eina_strbuf_append_printf ( freename , " %s_free_cb " , name ) ;
if ( eina_strbuf_length_get ( params ) )
eina_strbuf_append ( params , " , " ) ;
eina_strbuf_append_printf ( params , " %s, %s, %s " ,
eina_strbuf_string_get ( dataname ) ,
name ,
eina_strbuf_string_get ( freename ) ) ;
eina_strbuf_append_printf ( params_full_imp , " , void *%s, %s %s, Eina_Free_Cb %s " ,
eina_strbuf_string_get ( dataname ) ,
c_type , name ,
eina_strbuf_string_get ( freename ) ) ;
eina_strbuf_append_printf ( params_full , " , void *%s, %s %s, Eina_Free_Cb %s " ,
eina_strbuf_string_get ( dataname ) ,
c_type , name ,
eina_strbuf_string_get ( freename ) ) ;
eina_strbuf_free ( dataname ) ;
eina_strbuf_free ( freename ) ;
}
2016-12-14 08:32:32 -08:00
static void
2019-09-05 06:14:39 -07:00
_append_defval ( Eina_Strbuf * buf , const Eolian_Expression * exp , const Eolian_Type * tp , const char * ctp )
2016-12-14 08:32:32 -08:00
{
if ( exp )
{
2019-09-04 09:00:58 -07:00
Eolian_Value val = eolian_expression_eval ( exp , EOLIAN_MASK_ALL ) ;
2016-12-14 08:32:32 -08:00
Eina_Stringshare * lit = eolian_expression_value_to_literal ( & val ) ;
if ( lit )
{
eina_strbuf_append ( buf , lit ) ;
Eina_Stringshare * exps = eolian_expression_serialize ( exp ) ;
if ( exps & & strcmp ( lit , exps ) )
eina_strbuf_append_printf ( buf , " /* %s */ " , exps ) ;
eina_stringshare_del ( exps ) ;
eina_stringshare_del ( lit ) ;
return ;
}
else WRN ( " evaluation of default value failed " ) ;
}
/* default value or fallback */
2018-01-12 09:02:32 -08:00
const Eolian_Type * btp = eolian_type_aliased_base_get ( tp ) ;
2019-09-10 05:25:03 -07:00
if ( eolian_type_is_ptr ( btp ) | | strchr ( ctp , ' * ' ) )
2016-12-14 08:32:32 -08:00
{
eina_strbuf_append ( buf , " NULL " ) ;
return ;
}
2018-01-12 08:52:44 -08:00
const Eolian_Typedecl * tdcl = eolian_type_typedecl_get ( btp ) ;
2016-12-14 08:32:32 -08:00
if ( tdcl & & ( eolian_typedecl_type_get ( tdcl ) = = EOLIAN_TYPEDECL_STRUCT ) )
{
2018-03-12 08:28:28 -07:00
char * sn = eo_gen_c_full_name_get ( eolian_typedecl_name_get ( tdcl ) ) ;
2017-09-13 19:59:44 -07:00
if ( eina_streq ( sn , " Eina_Rect " ) )
eina_strbuf_append ( buf , " (EINA_RECT_EMPTY()) " ) ;
else
eina_strbuf_append_printf ( buf , " ((%s){0}) " , sn ) ;
2016-12-14 08:32:32 -08:00
free ( sn ) ;
return ;
}
/* enums and remaining regulars... 0 should do */
eina_strbuf_append ( buf , " 0 " ) ;
}
2019-07-03 05:45:02 -07:00
static const char *
_free_func_get ( const Eolian_Type * type )
{
const Eolian_Type * ab = eolian_type_aliased_base_get ( type ) ;
switch ( eolian_type_builtin_type_get ( ab ) )
{
/* simple types */
case EOLIAN_TYPE_BUILTIN_MSTRING :
return " free " ;
case EOLIAN_TYPE_BUILTIN_STRINGSHARE :
return " eina_stringshare_del " ;
case EOLIAN_TYPE_BUILTIN_ANY_VALUE :
return " eina_value_flush " ;
2019-09-20 09:02:07 -07:00
case EOLIAN_TYPE_BUILTIN_ANY_VALUE_REF :
2019-07-03 05:45:02 -07:00
return " eina_value_free " ;
2019-07-30 06:54:23 -07:00
case EOLIAN_TYPE_BUILTIN_STRBUF :
return " eina_strbuf_free " ;
case EOLIAN_TYPE_BUILTIN_BINBUF :
return " eina_binbuf_free " ;
2019-07-03 05:45:02 -07:00
/* complex types */
case EOLIAN_TYPE_BUILTIN_ACCESSOR :
return " eina_accessor_free " ;
case EOLIAN_TYPE_BUILTIN_ARRAY :
return " eina_array_free " ;
case EOLIAN_TYPE_BUILTIN_FUTURE :
return " (void) " ;
case EOLIAN_TYPE_BUILTIN_ITERATOR :
return " eina_iterator_free " ;
case EOLIAN_TYPE_BUILTIN_HASH :
return " eina_hash_free " ;
case EOLIAN_TYPE_BUILTIN_LIST :
return " eina_list_free " ;
/* class and user types */
case EOLIAN_TYPE_BUILTIN_INVALID :
if ( eolian_type_type_get ( ab ) = = EOLIAN_TYPE_CLASS )
return " efl_del " ;
else
2019-07-03 08:52:04 -07:00
return eolian_typedecl_free_func_get ( eolian_type_typedecl_get ( ab ) ) ;
2019-07-03 05:45:02 -07:00
/* no free func */
default :
return NULL ;
}
}
2017-09-14 06:12:30 -07:00
static void
_generate_normal_free ( Eina_Strbuf * * buf , const Eolian_Type * type , const Eina_Strbuf * parameter , const char * additional_intention )
{
2019-07-03 05:45:02 -07:00
const char * free_func = _free_func_get ( type ) ;
2017-09-29 04:00:07 -07:00
if ( ! free_func )
2017-09-14 06:12:30 -07:00
{
2018-03-12 08:28:28 -07:00
printf ( " No free type %s \n " , eolian_type_short_name_get ( type ) ) ;
2017-09-29 04:00:07 -07:00
return ;
2017-09-14 06:12:30 -07:00
}
2017-09-29 04:00:07 -07:00
if ( eolian_type_builtin_type_get ( type ) = = EOLIAN_TYPE_BUILTIN_HASH )
2017-09-14 06:12:30 -07:00
{
eina_strbuf_append_printf ( * buf , " eina_hash_free_cb_set( " ) ;
eina_strbuf_append_buffer ( * buf , parameter ) ;
eina_strbuf_append ( * buf , " ,NULL); \n " ) ;
}
eina_strbuf_append_printf ( * buf , " %s%s( " , additional_intention , free_func ) ;
eina_strbuf_append_buffer ( * buf , parameter ) ;
eina_strbuf_append ( * buf , " ); \n " ) ;
}
static void
_generate_loop_content ( Eina_Strbuf * * buf , const Eolian_Type * inner_type , const Eina_Strbuf * iter_param )
{
eina_strbuf_append ( * buf , " { \n " ) ;
_generate_normal_free ( buf , inner_type , iter_param , " " ) ;
eina_strbuf_append ( * buf , " } \n " ) ;
}
static void
2018-01-16 07:36:45 -08:00
_generate_iterative_free ( Eina_Strbuf * * buf , const Eolian_Type * type , const Eolian_Type * inner_type , Eolian_Function_Parameter * parameter , Eina_Strbuf * param )
2017-09-14 06:12:30 -07:00
{
Eina_Strbuf * iterator_header , * iter_param ;
iterator_header = eina_strbuf_new ( ) ;
iter_param = eina_strbuf_new ( ) ;
2017-12-04 14:32:06 -08:00
Eolian_Type_Builtin_Type t = eolian_type_builtin_type_get ( type ) ;
2017-09-14 06:12:30 -07:00
eina_strbuf_append_printf ( iter_param , " %s_iter " , eolian_parameter_name_get ( parameter ) ) ;
//generate the field definition
2019-09-09 09:26:49 -07:00
eina_strbuf_append_printf ( * buf , " %s " , eolian_type_c_type_get ( inner_type ) ) ;
2017-09-14 06:12:30 -07:00
eina_strbuf_append_buffer ( * buf , iter_param ) ;
eina_strbuf_append ( * buf , " ; \n " ) ;
if ( t = = EOLIAN_TYPE_BUILTIN_LIST )
{
eina_strbuf_append_printf ( * buf , " EINA_LIST_FREE( " ) ;
eina_strbuf_append_buffer ( * buf , param ) ;
eina_strbuf_append_char ( * buf , ' , ' ) ;
eina_strbuf_append_buffer ( * buf , iter_param ) ;
eina_strbuf_append ( * buf , " ) \n " ) ;
_generate_loop_content ( buf , inner_type , iter_param ) ;
2017-12-04 14:32:06 -08:00
}
2017-09-14 06:12:30 -07:00
else if ( t = = EOLIAN_TYPE_BUILTIN_ITERATOR )
{
eina_strbuf_append_printf ( * buf , " EINA_ITERATOR_FOREACH( " ) ;
eina_strbuf_append_buffer ( * buf , param ) ;
eina_strbuf_append_char ( * buf , ' , ' ) ;
eina_strbuf_append_buffer ( * buf , iter_param ) ;
eina_strbuf_append ( * buf , " ) \n " ) ;
_generate_loop_content ( buf , inner_type , iter_param ) ;
}
else if ( t = = EOLIAN_TYPE_BUILTIN_ACCESSOR )
{
eina_strbuf_append_printf ( * buf , " unsigned int %s_i = 0; \n " , eolian_parameter_name_get ( parameter ) ) ;
eina_strbuf_append_printf ( * buf , " EINA_ACCESSOR_FOREACH( " ) ;
eina_strbuf_append_buffer ( * buf , param ) ;
eina_strbuf_append_printf ( * buf , " ,%s_i, " , eolian_parameter_name_get ( parameter ) ) ;
eina_strbuf_append_buffer ( * buf , iter_param ) ;
eina_strbuf_append ( * buf , " ) \n " ) ;
_generate_loop_content ( buf , inner_type , iter_param ) ;
}
else if ( t = = EOLIAN_TYPE_BUILTIN_HASH )
{
eina_strbuf_append_printf ( * buf , " eina_hash_free_cb_set( " ) ;
eina_strbuf_append_buffer ( * buf , param ) ;
2019-07-03 05:45:02 -07:00
eina_strbuf_append_printf ( * buf , " ,%s); \n " , _free_func_get ( inner_type ) ) ;
2017-09-14 06:12:30 -07:00
eina_strbuf_append_printf ( * buf , " eina_hash_free( " ) ;
eina_strbuf_append_buffer ( * buf , param ) ;
eina_strbuf_append ( * buf , " ); \n " ) ;
}
2019-01-23 05:39:44 -08:00
else if ( t = = EOLIAN_TYPE_BUILTIN_ARRAY )
{
eina_strbuf_append_printf ( * buf , " while(( " ) ;
eina_strbuf_append_buffer ( * buf , iter_param ) ;
eina_strbuf_append_printf ( * buf , " = eina_array_pop( " ) ;
eina_strbuf_append_buffer ( * buf , param ) ;
eina_strbuf_append_printf ( * buf , " ))) \n " ) ;
_generate_loop_content ( buf , inner_type , iter_param ) ;
eina_strbuf_append_printf ( * buf , " eina_array_free( " ) ;
eina_strbuf_append_buffer ( * buf , param ) ;
eina_strbuf_append_printf ( * buf , " ); \n " ) ;
}
2017-09-14 06:12:30 -07:00
else
{
2017-12-04 14:32:06 -08:00
printf ( " Error, container unknown?! %d \n " , ( int ) t ) ;
2017-09-14 06:12:30 -07:00
}
eina_strbuf_free ( iterator_header ) ;
eina_strbuf_free ( iter_param ) ;
}
2019-01-15 09:13:43 -08:00
static int
_gen_function_param_fallback ( Eina_Iterator * itr , Eina_Strbuf * fallback_free_ownership , Eina_Strbuf * param_call )
{
Eolian_Function_Parameter * pr ;
int owners = 0 ;
EINA_ITERATOR_FOREACH ( itr , pr )
{
const Eolian_Type * type , * inner_type ;
type = eolian_parameter_type_get ( pr ) ;
inner_type = eolian_type_base_type_get ( type ) ;
//check if they should be freed or just ignored
2019-09-02 06:05:34 -07:00
if ( ! eolian_parameter_is_move ( pr ) | | eolian_parameter_direction_get ( pr ) = = EOLIAN_OUT_PARAM )
2019-01-15 09:13:43 -08:00
{
eina_strbuf_append_printf ( fallback_free_ownership , " (void)%s; \n " , eolian_parameter_name_get ( pr ) ) ;
continue ;
}
owners + + ;
eina_strbuf_reset ( param_call ) ;
if ( eolian_parameter_direction_get ( pr ) = = EOLIAN_INOUT_PARAM )
eina_strbuf_append_char ( param_call , ' * ' ) ;
eina_strbuf_append ( param_call , eolian_parameter_name_get ( pr ) ) ;
//check if we might want to free or handle the children
2019-09-02 06:05:34 -07:00
if ( ! inner_type | | ! eolian_type_is_move ( inner_type ) )
2019-01-15 09:13:43 -08:00
{
_generate_normal_free ( & fallback_free_ownership , type , param_call , " " ) ;
}
2019-09-02 06:05:34 -07:00
else if ( inner_type & & eolian_type_is_move ( inner_type ) )
2019-01-15 09:13:43 -08:00
{
_generate_iterative_free ( & fallback_free_ownership , type , inner_type , pr , param_call ) ;
}
}
eina_iterator_free ( itr ) ;
return owners ;
}
2019-02-15 08:15:36 -08:00
static const char *
_get_reflect_initf ( const Eolian_Type * abtp )
{
Eolian_Type_Builtin_Type btp = eolian_type_builtin_type_get ( abtp ) ;
const char * initf = NULL ;
switch ( btp )
{
case EOLIAN_TYPE_BUILTIN_BYTE :
case EOLIAN_TYPE_BUILTIN_CHAR :
initf = " char " ; break ;
case EOLIAN_TYPE_BUILTIN_UBYTE :
initf = " uchar " ; break ;
case EOLIAN_TYPE_BUILTIN_SHORT :
case EOLIAN_TYPE_BUILTIN_USHORT :
case EOLIAN_TYPE_BUILTIN_INT :
case EOLIAN_TYPE_BUILTIN_UINT :
case EOLIAN_TYPE_BUILTIN_LONG :
case EOLIAN_TYPE_BUILTIN_ULONG :
case EOLIAN_TYPE_BUILTIN_INT64 :
case EOLIAN_TYPE_BUILTIN_UINT64 :
case EOLIAN_TYPE_BUILTIN_TIME :
case EOLIAN_TYPE_BUILTIN_FLOAT :
case EOLIAN_TYPE_BUILTIN_DOUBLE :
case EOLIAN_TYPE_BUILTIN_BOOL :
case EOLIAN_TYPE_BUILTIN_STRING :
case EOLIAN_TYPE_BUILTIN_STRINGSHARE :
initf = eolian_type_name_get ( abtp ) ; break ;
default :
break ;
}
return initf ;
}
static void
2019-09-05 06:14:39 -07:00
_gen_reflect_get ( Eina_Strbuf * buf , const char * cnamel ,
const Eolian_Function_Parameter * pr ,
2019-02-15 08:15:36 -08:00
const Eolian_Function * fid , Eina_Hash * refh )
{
2019-09-05 06:14:39 -07:00
const Eolian_Type * valt = eolian_parameter_type_get ( pr ) ;
2019-02-15 08:15:36 -08:00
if ( eolian_type_is_ptr ( valt ) )
return ;
const Eolian_Type * abtp = eolian_type_aliased_base_get ( valt ) ;
const char * initf = _get_reflect_initf ( abtp ) ;
if ( ! initf )
return ;
Eolian_Function_Type et = ( Eolian_Function_Type ) eina_hash_find ( refh , & fid ) ;
if ( et = = EOLIAN_PROP_SET )
eina_hash_set ( refh , & fid , ( void * ) EOLIAN_PROPERTY ) ;
else
eina_hash_set ( refh , & fid , ( void * ) EOLIAN_PROP_GET ) ;
eina_strbuf_append ( buf , " \n static Eina_Value \n " ) ;
2019-02-15 13:48:59 -08:00
eina_strbuf_append_printf ( buf , " __eolian_%s_%s_get_reflect(const Eo *obj) \n " ,
2019-02-15 08:15:36 -08:00
cnamel , eolian_function_name_get ( fid ) ) ;
eina_strbuf_append ( buf , " { \n " ) ;
2019-09-05 06:14:39 -07:00
Eina_Stringshare * ct = eolian_parameter_c_type_get ( pr , EINA_TRUE ) ;
2019-02-15 08:15:36 -08:00
const char * starsp = ( ct [ strlen ( ct ) - 1 ] ! = ' * ' ) ? " " : " " ;
2019-03-08 06:58:52 -08:00
Eina_Stringshare * fcn = eolian_function_full_c_name_get ( fid , EOLIAN_PROP_GET ) ;
2019-02-15 08:15:36 -08:00
eina_strbuf_append_printf ( buf , " %s%sval = %s(obj); \n " , ct , starsp , fcn ) ;
eina_stringshare_del ( fcn ) ;
eina_stringshare_del ( ct ) ;
eina_strbuf_append_printf ( buf , " return eina_value_%s_init(val); \n " , initf ) ;
eina_strbuf_append ( buf , " } \n \n " ) ;
}
static void
2019-09-05 06:14:39 -07:00
_gen_reflect_set ( Eina_Strbuf * buf , const char * cnamel ,
const Eolian_Function_Parameter * pr ,
2019-02-15 08:15:36 -08:00
const Eolian_Function * fid , Eina_Hash * refh )
{
2019-09-05 06:14:39 -07:00
const Eolian_Type * valt = eolian_parameter_type_get ( pr ) ;
2019-02-15 08:15:36 -08:00
if ( eolian_type_is_ptr ( valt ) )
return ;
const Eolian_Type * abtp = eolian_type_aliased_base_get ( valt ) ;
const char * initf = _get_reflect_initf ( abtp ) ;
if ( ! initf )
return ;
Eolian_Function_Type et = ( Eolian_Function_Type ) eina_hash_find ( refh , & fid ) ;
if ( et = = EOLIAN_PROP_GET )
eina_hash_set ( refh , & fid , ( void * ) EOLIAN_PROPERTY ) ;
else
eina_hash_set ( refh , & fid , ( void * ) EOLIAN_PROP_SET ) ;
2019-02-11 16:31:52 -08:00
eina_strbuf_append ( buf , " \n static Eina_Error \n " ) ;
2019-02-15 08:15:36 -08:00
eina_strbuf_append_printf ( buf , " __eolian_%s_%s_set_reflect(Eo *obj, Eina_Value val) \n " ,
cnamel , eolian_function_name_get ( fid ) ) ;
eina_strbuf_append ( buf , " { \n " ) ;
2019-02-11 16:31:52 -08:00
eina_strbuf_append ( buf , " Eina_Error r = 0; " ) ;
2019-02-15 08:15:36 -08:00
2019-09-05 06:14:39 -07:00
Eina_Stringshare * ct = eolian_parameter_c_type_get ( pr , EINA_FALSE ) ;
2019-02-15 08:15:36 -08:00
const char * starsp = ( ct [ strlen ( ct ) - 1 ] ! = ' * ' ) ? " " : " " ;
eina_strbuf_append_printf ( buf , " %s%scval; \n " , ct , starsp ) ;
eina_stringshare_del ( ct ) ;
2019-02-11 16:31:52 -08:00
eina_strbuf_append_printf ( buf , " if (!eina_value_%s_convert(&val, &cval)) \n " , initf ) ;
eina_strbuf_append ( buf , " { \n " ) ;
eina_strbuf_append ( buf , " r = EINA_ERROR_VALUE_FAILED; \n " ) ;
eina_strbuf_append ( buf , " goto end; \n " ) ;
eina_strbuf_append ( buf , " } \n " ) ;
2019-02-15 08:15:36 -08:00
2019-03-08 06:58:52 -08:00
Eina_Stringshare * fcn = eolian_function_full_c_name_get ( fid , EOLIAN_PROP_SET ) ;
2019-02-15 08:15:36 -08:00
eina_strbuf_append_printf ( buf , " %s(obj, cval); \n " , fcn ) ;
eina_stringshare_del ( fcn ) ;
2019-02-11 16:31:52 -08:00
eina_strbuf_append ( buf , " end: \n " ) ;
2019-02-15 08:15:36 -08:00
eina_strbuf_append ( buf , " eina_value_flush(&val); \n " ) ;
2019-02-11 16:31:52 -08:00
eina_strbuf_append ( buf , " return r; \n " ) ;
2019-02-15 08:15:36 -08:00
eina_strbuf_append ( buf , " } \n \n " ) ;
}
2019-01-15 09:13:43 -08:00
2019-02-27 01:04:56 -08:00
static void
2019-09-05 06:14:39 -07:00
_emit_class_function ( Eina_Strbuf * buf , const Eolian_Function * fid , const char * rtpn , Eina_Strbuf * params_full ,
2019-02-27 01:04:56 -08:00
const char * ocnamel , const char * func_suffix , Eina_Strbuf * params , const char * function_name )
{
eina_strbuf_append ( buf , " EOAPI " ) ;
2019-09-05 06:14:39 -07:00
eina_strbuf_append ( buf , rtpn ) ;
2019-02-27 01:04:56 -08:00
eina_strbuf_append ( buf , " " ) ;
eina_strbuf_append ( buf , function_name ) ;
eina_strbuf_append ( buf , " ( " ) ;
if ( eina_strbuf_length_get ( params_full ) = = 0 )
eina_strbuf_append ( buf , " void " ) ;
else
eina_strbuf_append_buffer ( buf , params_full ) ;
eina_strbuf_append ( buf , " ) \n " ) ;
eina_strbuf_append ( buf , " { \n " ) ;
eina_strbuf_append_printf ( buf , " %s(); \n " , eolian_class_c_get_function_name_get ( eolian_function_class_get ( fid ) ) ) ;
2019-09-05 06:14:39 -07:00
if ( strcmp ( rtpn , " void " ) )
2019-02-27 01:04:56 -08:00
eina_strbuf_append ( buf , " return " ) ;
else
eina_strbuf_append ( buf , " " ) ;
eina_strbuf_append_printf ( buf , " _%s " , ocnamel ) ;
eina_strbuf_append_char ( buf , ' _ ' ) ;
eina_strbuf_append ( buf , eolian_function_name_get ( fid ) ) ;
eina_strbuf_append ( buf , func_suffix ) ;
eina_strbuf_append ( buf , " ( " ) ;
eina_strbuf_append_buffer ( buf , params ) ;
eina_strbuf_append ( buf , " ); \n " ) ;
eina_strbuf_append ( buf , " } \n " ) ;
}
2016-09-23 08:49:44 -07:00
static void
2018-01-16 07:36:45 -08:00
_gen_func ( const Eolian_Class * cl , const Eolian_Function * fid ,
Eolian_Function_Type ftype , Eina_Strbuf * buf ,
2019-03-08 06:58:52 -08:00
const Eolian_Implement * impl , Eina_Hash * refh )
2016-09-23 08:49:44 -07:00
{
2017-01-11 10:25:54 -08:00
Eina_Bool is_empty = eolian_implement_is_empty ( impl , ftype ) ;
Eina_Bool is_auto = eolian_implement_is_auto ( impl , ftype ) ;
2016-09-23 08:49:44 -07:00
if ( ( ftype ! = EOLIAN_PROP_GET ) & & ( ftype ! = EOLIAN_PROP_SET ) )
ftype = eolian_function_type_get ( fid ) ;
Eina_Bool is_prop = ( ftype = = EOLIAN_PROP_GET | | ftype = = EOLIAN_PROP_SET ) ;
Eina_Bool var_as_ret = EINA_FALSE ;
2019-02-15 08:15:36 -08:00
/* assume we're not generating reflection api by default */
2019-09-05 06:14:39 -07:00
const Eolian_Function_Parameter * reflect_param = NULL ;
2016-09-23 08:49:44 -07:00
const Eolian_Expression * def_ret = NULL ;
const Eolian_Type * rtp = eolian_function_return_type_get ( fid , ftype ) ;
2019-09-05 06:14:39 -07:00
Eina_Stringshare * rtpn = NULL ;
2016-09-23 08:49:44 -07:00
if ( rtp )
{
is_auto = EINA_FALSE ; /* can't do auto if func returns */
def_ret = eolian_function_return_default_value_get ( fid , ftype ) ;
2019-09-05 06:14:39 -07:00
rtpn = eolian_function_return_c_type_get ( fid , ftype ) ;
2016-09-23 08:49:44 -07:00
}
const char * func_suffix = " " ;
if ( ftype = = EOLIAN_PROP_GET )
{
func_suffix = " _get " ;
if ( ! rtp )
{
void * d1 , * d2 ;
Eina_Iterator * itr = eolian_property_values_get ( fid , ftype ) ;
if ( eina_iterator_next ( itr , & d1 ) & & ! eina_iterator_next ( itr , & d2 ) )
{
Eolian_Function_Parameter * pr = d1 ;
rtp = eolian_parameter_type_get ( pr ) ;
2019-02-15 08:15:36 -08:00
/* reflect only when returning 1 val */
2019-09-02 06:55:49 -07:00
if ( ! eolian_parameter_is_by_ref ( pr ) )
2019-09-05 06:14:39 -07:00
reflect_param = pr ;
2016-09-23 08:49:44 -07:00
var_as_ret = EINA_TRUE ;
def_ret = eolian_parameter_default_value_get ( pr ) ;
2019-09-05 06:14:39 -07:00
rtpn = eolian_parameter_c_type_get ( pr , EINA_TRUE ) ;
2016-09-23 08:49:44 -07:00
}
eina_iterator_free ( itr ) ;
}
}
else if ( ftype = = EOLIAN_PROP_SET )
2019-02-15 08:15:36 -08:00
{
func_suffix = " _set " ;
Eina_Iterator * itr = eolian_property_values_get ( fid , ftype ) ;
void * d1 , * d2 ;
/* reflect with 1 value */
if ( eina_iterator_next ( itr , & d1 ) & & ! eina_iterator_next ( itr , & d2 ) )
{
Eolian_Function_Parameter * pr = d1 ;
2019-09-02 06:55:49 -07:00
if ( ! eolian_parameter_is_by_ref ( pr ) )
2019-09-05 06:14:39 -07:00
reflect_param = pr ;
2019-02-15 08:15:36 -08:00
}
eina_iterator_free ( itr ) ;
}
2016-09-23 08:49:44 -07:00
Eina_Strbuf * params = eina_strbuf_new ( ) ; /* par1, par2, par3, ... */
Eina_Strbuf * params_full = eina_strbuf_new ( ) ; /* T par1, U par2, ... for decl */
Eina_Strbuf * params_full_imp = eina_strbuf_new ( ) ; /* as above, for impl */
Eina_Strbuf * params_init = eina_strbuf_new ( ) ; /* default value inits */
2017-09-14 06:12:30 -07:00
Eina_Strbuf * fallback_free_ownership = eina_strbuf_new ( ) ; /* list of function calls that are freeing the owned parameters, or doing nothing on the normal parameters, NULL if there is nothing owned*/
2016-09-23 08:49:44 -07:00
/* property keys */
{
Eina_Iterator * itr = eolian_property_keys_get ( fid , ftype ) ;
2019-02-15 08:15:36 -08:00
if ( itr ) /* has keys: no reflection */
2019-09-05 06:14:39 -07:00
reflect_param = NULL ;
2016-09-23 08:49:44 -07:00
Eolian_Function_Parameter * pr ;
EINA_ITERATOR_FOREACH ( itr , pr )
{
const char * prn = eolian_parameter_name_get ( pr ) ;
2019-09-05 06:14:39 -07:00
Eina_Stringshare * ptn = eolian_parameter_c_type_get ( pr , EINA_FALSE ) ;
2016-09-23 08:49:44 -07:00
if ( eina_strbuf_length_get ( params ) )
eina_strbuf_append ( params , " , " ) ;
eina_strbuf_append ( params , prn ) ;
2019-08-16 07:32:13 -07:00
if ( eina_strbuf_length_get ( params_full ) | | ! eolian_function_is_static ( fid ) )
2019-02-09 09:45:27 -08:00
{
eina_strbuf_append ( params_full , " , " ) ;
eina_strbuf_append ( params_full_imp , " , " ) ;
}
eina_strbuf_append_printf ( params_full , " %s " , ptn ) ;
eina_strbuf_append_printf ( params_full_imp , " %s " , ptn ) ;
2016-10-14 06:31:23 -07:00
if ( ptn [ strlen ( ptn ) - 1 ] ! = ' * ' )
2016-09-29 08:09:37 -07:00
{
eina_strbuf_append_char ( params_full , ' ' ) ;
eina_strbuf_append_char ( params_full_imp , ' ' ) ;
}
eina_strbuf_append ( params_full , prn ) ;
eina_strbuf_append ( params_full_imp , prn ) ;
2016-10-07 03:58:22 -07:00
if ( is_empty | | is_auto )
2016-09-23 08:49:44 -07:00
eina_strbuf_append ( params_full_imp , " EINA_UNUSED " ) ;
eina_stringshare_del ( ptn ) ;
}
eina_iterator_free ( itr ) ;
}
2017-09-14 06:12:30 -07:00
/* check if we have owning data that we would have to free in a error case */
if ( ftype = = EOLIAN_PROP_GET )
{
eina_strbuf_free ( fallback_free_ownership ) ;
fallback_free_ownership = NULL ;
}
else
{
Eina_Iterator * itr ;
int owners = 0 ;
Eina_Strbuf * param_call ;
param_call = eina_strbuf_new ( ) ;
if ( is_prop )
2019-01-15 09:13:43 -08:00
{
itr = eolian_property_values_get ( fid , ftype ) ;
owners + = _gen_function_param_fallback ( itr , fallback_free_ownership , param_call ) ;
itr = eolian_property_keys_get ( fid , ftype ) ;
owners + = _gen_function_param_fallback ( itr , fallback_free_ownership , param_call ) ;
}
2017-09-14 06:12:30 -07:00
else
{
2019-01-15 09:13:43 -08:00
itr = eolian_function_parameters_get ( fid ) ;
owners + = _gen_function_param_fallback ( itr , fallback_free_ownership , param_call ) ;
2017-09-14 06:12:30 -07:00
}
if ( owners = = 0 )
{
eina_strbuf_free ( fallback_free_ownership ) ;
fallback_free_ownership = NULL ;
}
2017-10-05 06:46:18 -07:00
eina_strbuf_free ( param_call ) ;
2017-09-14 06:12:30 -07:00
}
2016-09-23 08:49:44 -07:00
/* property values or method params if applicable */
if ( ! var_as_ret )
{
Eina_Iterator * itr ;
if ( is_prop )
itr = eolian_property_values_get ( fid , ftype ) ;
else
itr = eolian_function_parameters_get ( fid ) ;
Eolian_Function_Parameter * pr ;
EINA_ITERATOR_FOREACH ( itr , pr )
{
Eolian_Parameter_Dir pd = eolian_parameter_direction_get ( pr ) ;
const Eolian_Expression * dfv = eolian_parameter_default_value_get ( pr ) ;
const char * prn = eolian_parameter_name_get ( pr ) ;
const Eolian_Type * pt = eolian_parameter_type_get ( pr ) ;
2019-09-05 06:14:39 -07:00
Eina_Stringshare * ptn = eolian_parameter_c_type_get ( pr , EINA_FALSE ) ;
2018-01-12 08:52:44 -08:00
const Eolian_Typedecl * ptd = eolian_type_typedecl_get ( pt ) ;
2016-09-23 08:49:44 -07:00
2016-10-14 06:31:23 -07:00
Eina_Bool had_star = ptn [ strlen ( ptn ) - 1 ] = = ' * ' ;
2016-09-23 08:49:44 -07:00
const char * add_star = _get_add_star ( ftype , pd ) ;
2017-04-07 09:54:55 -07:00
if ( ptd & & eolian_typedecl_type_get ( ptd ) = = EOLIAN_TYPEDECL_FUNCTION_POINTER )
{
_gen_func_pointer_param ( prn , ptn , ptd , params , params_full , params_full_imp , is_empty ) ;
eina_stringshare_del ( ptn ) ;
continue ;
}
2016-09-23 08:49:44 -07:00
if ( eina_strbuf_length_get ( params ) )
eina_strbuf_append ( params , " , " ) ;
2019-08-16 07:32:13 -07:00
if ( eina_strbuf_length_get ( params_full_imp ) | | ! eolian_function_is_static ( fid ) )
2019-02-09 09:45:27 -08:00
eina_strbuf_append ( params_full_imp , " , " ) ;
2016-11-07 11:34:41 -08:00
eina_strbuf_append ( params_full_imp , ptn ) ;
if ( ! had_star )
eina_strbuf_append_char ( params_full_imp , ' ' ) ;
eina_strbuf_append ( params_full_imp , add_star ) ;
eina_strbuf_append ( params_full_imp , prn ) ;
if ( ! dfv & & is_empty )
eina_strbuf_append ( params_full_imp , " EINA_UNUSED " ) ;
eina_strbuf_append ( params , prn ) ;
2016-09-23 08:49:44 -07:00
2019-08-16 07:32:13 -07:00
if ( eina_strbuf_length_get ( params_full ) | | ! eolian_function_is_static ( fid ) )
2019-02-09 09:45:27 -08:00
eina_strbuf_append ( params_full , " , " ) ;
2016-09-23 08:49:44 -07:00
eina_strbuf_append ( params_full , ptn ) ;
if ( ! had_star )
eina_strbuf_append_char ( params_full , ' ' ) ;
eina_strbuf_append ( params_full , add_star ) ;
eina_strbuf_append ( params_full , prn ) ;
if ( is_auto )
{
if ( ftype = = EOLIAN_PROP_SET )
2017-10-13 14:48:34 -07:00
eina_strbuf_append_printf ( params_init , " pd->%s = %s; \n " , prn , prn ) ;
2016-09-23 08:49:44 -07:00
else
{
2016-10-07 03:58:22 -07:00
eina_strbuf_append_printf ( params_init , " if (%s) *%s = pd->%s; \n " ,
2016-09-23 08:49:44 -07:00
prn , prn , prn ) ;
}
}
else if ( ( ftype ! = EOLIAN_PROP_SET ) & & dfv )
{
2018-01-16 07:10:43 -08:00
Eolian_Value val = eolian_expression_eval ( dfv , EOLIAN_MASK_ALL ) ;
2016-09-23 08:49:44 -07:00
if ( val . type )
{
Eina_Stringshare * vals = eolian_expression_value_to_literal ( & val ) ;
eina_strbuf_append_printf ( params_init , " if (%s) *%s = %s; " ,
prn , prn , vals ) ;
eina_stringshare_del ( vals ) ;
if ( eolian_expression_type_get ( dfv ) = = EOLIAN_EXPR_NAME )
{
Eina_Stringshare * vs = eolian_expression_serialize ( dfv ) ;
eina_strbuf_append_printf ( params_init , " /* %s */ " , vs ) ;
eina_stringshare_del ( vs ) ;
}
eina_strbuf_append_char ( params_init , ' \n ' ) ;
}
}
eina_stringshare_del ( ptn ) ;
}
eina_iterator_free ( itr ) ;
}
Eina_Bool impl_same_class = ( eolian_implement_class_get ( impl ) = = cl ) ;
Eina_Bool impl_need = EINA_TRUE ;
2017-01-16 06:51:11 -08:00
if ( impl_same_class & & eolian_implement_is_pure_virtual ( impl , ftype ) )
2016-09-23 08:49:44 -07:00
impl_need = EINA_FALSE ;
2019-09-05 06:14:39 -07:00
if ( ! rtpn )
rtpn = eina_stringshare_add ( " void " ) ;
2016-09-23 08:49:44 -07:00
2016-10-12 06:05:46 -07:00
char * cname = NULL , * cnamel = NULL , * ocnamel = NULL ;
eo_gen_class_names_get ( cl , & cname , NULL , & cnamel ) ;
2016-09-29 08:19:30 -07:00
eo_gen_class_names_get ( eolian_implement_class_get ( impl ) , NULL , NULL , & ocnamel ) ;
2016-09-23 08:49:44 -07:00
if ( impl_need )
{
/* figure out the data type */
2016-10-13 06:03:50 -07:00
Eina_Stringshare * dt = NULL ;
2019-08-16 07:32:13 -07:00
if ( eolian_function_is_static ( fid ) )
2016-10-13 06:03:50 -07:00
dt = eina_stringshare_add ( " void " ) ;
2016-09-23 08:49:44 -07:00
else
2016-10-13 06:03:50 -07:00
dt = eolian_class_c_data_type_get ( cl ) ;
2016-09-23 08:49:44 -07:00
eina_strbuf_append_char ( buf , ' \n ' ) ;
/* no need for prototype with empty/auto impl */
if ( ! is_empty & & ! is_auto )
{
/* T _class_name[_orig_class]_func_name_suffix */
eina_strbuf_append ( buf , rtpn ) ;
2016-10-14 06:31:23 -07:00
if ( rtpn [ strlen ( rtpn ) - 1 ] ! = ' * ' )
2016-09-23 08:49:44 -07:00
eina_strbuf_append_char ( buf , ' ' ) ;
eina_strbuf_append_char ( buf , ' _ ' ) ;
eina_strbuf_append ( buf , cnamel ) ;
if ( ! impl_same_class )
eina_strbuf_append_printf ( buf , " _%s " , ocnamel ) ;
eina_strbuf_append_char ( buf , ' _ ' ) ;
eina_strbuf_append ( buf , eolian_function_name_get ( fid ) ) ;
eina_strbuf_append ( buf , func_suffix ) ;
/* ([const ]Eo *obj, Data_Type *pd, impl_full_params); */
eina_strbuf_append_char ( buf , ' ( ' ) ;
2019-08-16 07:32:13 -07:00
if ( ! eolian_function_is_static ( fid ) )
2019-02-09 09:45:27 -08:00
{
if ( ( ftype = = EOLIAN_PROP_GET ) | | eolian_function_object_is_const ( fid ) )
eina_strbuf_append ( buf , " const " ) ;
eina_strbuf_append ( buf , " Eo *obj, " ) ;
eina_strbuf_append ( buf , dt ) ;
eina_strbuf_append ( buf , " *pd " ) ;
}
2016-09-23 08:49:44 -07:00
eina_strbuf_append ( buf , eina_strbuf_string_get ( params_full_imp ) ) ;
2019-08-16 07:32:13 -07:00
if ( eina_strbuf_length_get ( params_full_imp ) = = 0 & & eolian_function_is_static ( fid ) )
2019-02-09 09:45:27 -08:00
eina_strbuf_append ( buf , " void " ) ;
2016-09-23 08:49:44 -07:00
eina_strbuf_append ( buf , " ); \n \n " ) ;
}
if ( is_empty | | is_auto | | eina_strbuf_length_get ( params_init ) )
{
/* we need to give the internal function name to Eo,
* use this hash table as indication
*/
2016-12-27 08:16:17 -08:00
if ( ftype = = EOLIAN_PROP_SET )
eina_hash_add ( _funcs_params_init_set , & impl , impl ) ;
else
eina_hash_add ( _funcs_params_init_get , & impl , impl ) ;
2016-09-23 08:49:44 -07:00
/* generation of intermediate __eolian_... */
eina_strbuf_append ( buf , " static " ) ;
eina_strbuf_append ( buf , rtpn ) ;
2016-10-14 06:31:23 -07:00
if ( rtpn [ strlen ( rtpn ) - 1 ] ! = ' * ' )
2016-09-23 08:49:44 -07:00
eina_strbuf_append_char ( buf , ' ' ) ;
eina_strbuf_append ( buf , " __eolian_ " ) ;
eina_strbuf_append ( buf , cnamel ) ;
if ( ! impl_same_class )
eina_strbuf_append_printf ( buf , " _%s " , ocnamel ) ;
eina_strbuf_append_char ( buf , ' _ ' ) ;
eina_strbuf_append ( buf , eolian_function_name_get ( fid ) ) ;
eina_strbuf_append ( buf , func_suffix ) ;
eina_strbuf_append_char ( buf , ' ( ' ) ;
2018-04-17 11:09:44 -07:00
if ( ( ftype = = EOLIAN_PROP_GET ) | | eolian_function_object_is_const ( fid ) )
2016-09-23 08:49:44 -07:00
eina_strbuf_append ( buf , " const " ) ;
eina_strbuf_append ( buf , " Eo *obj " ) ;
if ( is_empty | | is_auto )
eina_strbuf_append ( buf , " EINA_UNUSED " ) ;
eina_strbuf_append ( buf , " , " ) ;
2016-10-13 06:03:50 -07:00
eina_strbuf_append ( buf , dt ) ;
2016-09-23 08:49:44 -07:00
eina_strbuf_append ( buf , " *pd " ) ;
2016-10-07 03:58:22 -07:00
if ( is_empty | | ( is_auto & & ! eina_strbuf_length_get ( params_init ) ) )
eina_strbuf_append ( buf , " EINA_UNUSED " ) ;
2016-09-23 08:49:44 -07:00
eina_strbuf_append ( buf , eina_strbuf_string_get ( params_full_imp ) ) ;
eina_strbuf_append ( buf , " ) \n { \n " ) ;
}
if ( eina_strbuf_length_get ( params_init ) )
eina_strbuf_append ( buf , eina_strbuf_string_get ( params_init ) ) ;
if ( is_empty | | is_auto )
{
if ( rtp )
{
2016-12-14 08:32:32 -08:00
eina_strbuf_append ( buf , " return " ) ;
2019-09-05 06:14:39 -07:00
_append_defval ( buf , def_ret , rtp , rtpn ) ;
2016-12-14 08:32:32 -08:00
eina_strbuf_append ( buf , " ; \n " ) ;
2016-09-23 08:49:44 -07:00
}
eina_strbuf_append ( buf , " } \n \n " ) ;
}
else if ( eina_strbuf_length_get ( params_init ) )
{
eina_strbuf_append ( buf , " " ) ;
if ( rtp )
eina_strbuf_append ( buf , " return " ) ;
eina_strbuf_append_char ( buf , ' _ ' ) ;
eina_strbuf_append ( buf , cnamel ) ;
if ( ! impl_same_class )
eina_strbuf_append_printf ( buf , " _%s " , ocnamel ) ;
eina_strbuf_append_char ( buf , ' _ ' ) ;
eina_strbuf_append ( buf , eolian_function_name_get ( fid ) ) ;
eina_strbuf_append ( buf , func_suffix ) ;
eina_strbuf_append ( buf , " (obj, pd, " ) ;
eina_strbuf_append ( buf , eina_strbuf_string_get ( params ) ) ;
eina_strbuf_append ( buf , " ); \n } \n \n " ) ;
}
2016-10-13 06:03:50 -07:00
eina_stringshare_del ( dt ) ;
2016-09-23 08:49:44 -07:00
}
2019-08-16 07:32:13 -07:00
if ( impl_same_class & & ! eolian_function_is_static ( fid ) )
2016-09-23 08:49:44 -07:00
{
2019-02-15 08:15:36 -08:00
/* generate reflection implementation */
2019-09-05 06:14:39 -07:00
if ( reflect_param )
2019-02-15 08:15:36 -08:00
{
if ( ftype = = EOLIAN_PROP_GET )
2019-09-05 06:14:39 -07:00
_gen_reflect_get ( buf , cnamel , reflect_param , fid , refh ) ;
2019-02-15 08:15:36 -08:00
else
2019-09-05 06:14:39 -07:00
_gen_reflect_set ( buf , cnamel , reflect_param , fid , refh ) ;
2019-02-15 08:15:36 -08:00
}
2016-09-23 08:49:44 -07:00
void * data ;
Eina_Iterator * itr = eolian_property_keys_get ( fid , ftype ) ;
Eina_Bool has_params = eina_iterator_next ( itr , & data ) ;
eina_iterator_free ( itr ) ;
if ( ! has_params & & ! var_as_ret )
{
if ( is_prop )
itr = eolian_property_values_get ( fid , ftype ) ;
else
itr = eolian_function_parameters_get ( fid ) ;
has_params = eina_iterator_next ( itr , & data ) ;
eina_iterator_free ( itr ) ;
}
2017-09-14 06:12:30 -07:00
if ( fallback_free_ownership )
{
//we have owned parameters we need to take care of
eina_strbuf_append_printf ( buf , " static void \n " ) ;
2019-03-08 06:58:52 -08:00
eina_strbuf_append_printf ( buf , " _%s_ownership_fallback(%s) \n { \n " , eolian_function_full_c_name_get ( fid , ftype ) , eina_strbuf_string_get ( params_full ) + 2 ) ;
2017-09-14 06:12:30 -07:00
eina_strbuf_append_buffer ( buf , fallback_free_ownership ) ;
eina_strbuf_append_printf ( buf , " } \n \n " ) ;
}
2016-09-23 08:49:44 -07:00
eina_strbuf_append ( buf , " EOAPI EFL_ " ) ;
if ( ! strcmp ( rtpn , " void " ) )
eina_strbuf_append ( buf , " VOID_ " ) ;
eina_strbuf_append ( buf , " FUNC_BODY " ) ;
if ( has_params )
eina_strbuf_append_char ( buf , ' V ' ) ;
if ( ( ftype = = EOLIAN_PROP_GET ) | | eolian_function_object_is_const ( fid )
2019-08-16 07:32:13 -07:00
| | eolian_function_is_static ( fid ) )
2016-09-23 08:49:44 -07:00
{
eina_strbuf_append ( buf , " _CONST " ) ;
}
2017-09-14 06:12:30 -07:00
if ( fallback_free_ownership )
eina_strbuf_append ( buf , " _FALLBACK " ) ;
2016-09-23 08:49:44 -07:00
eina_strbuf_append_char ( buf , ' ( ' ) ;
2019-03-08 06:58:52 -08:00
Eina_Stringshare * eofn = eolian_function_full_c_name_get ( fid , ftype ) ;
2016-09-23 08:49:44 -07:00
eina_strbuf_append ( buf , eofn ) ;
if ( strcmp ( rtpn , " void " ) )
{
2016-12-14 08:32:32 -08:00
eina_strbuf_append_printf ( buf , " , %s, " , rtpn ) ;
2019-09-05 06:14:39 -07:00
_append_defval ( buf , def_ret , rtp , rtpn ) ;
2016-09-23 08:49:44 -07:00
}
2017-09-14 06:12:30 -07:00
if ( fallback_free_ownership )
2019-03-08 06:58:52 -08:00
eina_strbuf_append_printf ( buf , " , _%s_ownership_fallback(%s); " , eolian_function_full_c_name_get ( fid , ftype ) , eina_strbuf_string_get ( params ) ) ;
2017-09-14 06:12:30 -07:00
2016-09-23 08:49:44 -07:00
if ( has_params )
{
eina_strbuf_append ( buf , " , EFL_FUNC_CALL( " ) ;
eina_strbuf_append ( buf , eina_strbuf_string_get ( params ) ) ;
eina_strbuf_append_char ( buf , ' ) ' ) ;
eina_strbuf_append ( buf , eina_strbuf_string_get ( params_full ) ) ;
}
eina_strbuf_append ( buf , " ); \n " ) ;
2016-09-29 08:09:37 -07:00
eina_stringshare_del ( eofn ) ;
2016-09-23 08:49:44 -07:00
}
2019-08-16 07:32:13 -07:00
if ( impl_same_class & & eolian_function_is_static ( fid ) )
2019-09-05 06:14:39 -07:00
_emit_class_function ( buf , fid , rtpn , params_full , ocnamel , func_suffix , params , eolian_function_full_c_name_get ( fid , ftype ) ) ;
2016-09-23 08:49:44 -07:00
2016-09-29 08:09:37 -07:00
free ( cname ) ;
2016-09-23 08:49:44 -07:00
free ( cnamel ) ;
free ( ocnamel ) ;
eina_stringshare_del ( rtpn ) ;
eina_strbuf_free ( params ) ;
eina_strbuf_free ( params_full ) ;
eina_strbuf_free ( params_full_imp ) ;
eina_strbuf_free ( params_init ) ;
2017-09-14 06:12:30 -07:00
if ( fallback_free_ownership )
eina_strbuf_free ( fallback_free_ownership ) ;
2016-09-23 08:49:44 -07:00
}
2016-09-28 08:41:50 -07:00
static void
_gen_opfunc ( const Eolian_Function * fid , Eolian_Function_Type ftype ,
2017-01-16 06:51:11 -08:00
Eina_Strbuf * buf , const Eolian_Implement * impl , Eina_Bool pinit ,
2016-09-28 08:41:50 -07:00
const char * cnamel , const char * ocnamel )
{
2019-03-08 06:58:52 -08:00
Eina_Stringshare * fnm = eolian_function_full_c_name_get ( fid , ftype ) ;
2016-09-28 08:41:50 -07:00
eina_strbuf_append ( buf , " EFL_OBJECT_OP_FUNC( " ) ;
eina_strbuf_append ( buf , fnm ) ;
eina_strbuf_append ( buf , " , " ) ;
2017-01-16 06:51:11 -08:00
if ( ! ocnamel & & eolian_implement_is_pure_virtual ( impl , ftype ) )
2016-09-28 08:41:50 -07:00
eina_strbuf_append ( buf , " NULL), \n " ) ;
else
{
if ( pinit )
eina_strbuf_append ( buf , " __eolian " ) ;
eina_strbuf_append_printf ( buf , " _%s_ " , cnamel ) ;
if ( ocnamel )
eina_strbuf_append_printf ( buf , " %s_ " , ocnamel ) ;
eina_strbuf_append ( buf , eolian_function_name_get ( fid ) ) ;
if ( ftype = = EOLIAN_PROP_GET )
eina_strbuf_append ( buf , " _get " ) ;
else if ( ftype = = EOLIAN_PROP_SET )
eina_strbuf_append ( buf , " _set " ) ;
eina_strbuf_append ( buf , " ), \n " ) ;
}
}
2017-07-17 02:04:29 -07:00
static void
2019-02-15 08:15:36 -08:00
_gen_reflop ( const Eolian_Function * fid , Eina_Strbuf * buf , const char * cnamel , Eina_Hash * refh )
{
Eolian_Function_Type aftype = ( Eolian_Function_Type ) eina_hash_find ( refh , & fid ) ;
if ( aftype = = EOLIAN_UNRESOLVED )
return ;
eina_strbuf_append_printf ( buf , " { \" %s \" , " , eolian_function_name_get ( fid ) ) ;
if ( aftype = = EOLIAN_PROP_SET | | aftype = = EOLIAN_PROPERTY )
{
eina_strbuf_append_printf ( buf , " __eolian_%s_%s_set_reflect, " ,
cnamel , eolian_function_name_get ( fid ) ) ;
}
else
eina_strbuf_append ( buf , " NULL, " ) ;
if ( aftype = = EOLIAN_PROP_GET | | aftype = = EOLIAN_PROPERTY )
{
eina_strbuf_append_printf ( buf , " __eolian_%s_%s_get_reflect}, \n " ,
cnamel , eolian_function_name_get ( fid ) ) ;
}
else
eina_strbuf_append ( buf , " NULL}, \n " ) ;
}
static void
_gen_initializer ( const Eolian_Class * cl , Eina_Strbuf * buf , Eina_Hash * refh )
2016-09-28 08:41:50 -07:00
{
2017-04-13 06:56:15 -07:00
char * cnamel = NULL , * cnameu = NULL ;
eo_gen_class_names_get ( cl , NULL , & cnameu , & cnamel ) ;
2016-09-28 08:41:50 -07:00
eina_strbuf_append ( buf , " \n static Eina_Bool \n _ " ) ;
eina_strbuf_append ( buf , cnamel ) ;
eina_strbuf_append ( buf , " _class_initializer(Efl_Class *klass) \n { \n " ) ;
2019-02-09 09:45:27 -08:00
eina_strbuf_append ( buf , " const Efl_Object_Ops *opsp = NULL; \n \n " ) ;
2019-02-15 08:15:36 -08:00
eina_strbuf_append ( buf , " const Efl_Object_Property_Reflection_Ops *ropsp = NULL; \n \n " ) ;
2016-09-28 08:41:50 -07:00
2019-02-09 09:45:27 -08:00
Eina_Strbuf * ops = eina_strbuf_new ( ) ;
2019-02-15 08:15:36 -08:00
Eina_Strbuf * refls = eina_strbuf_new ( ) ;
2016-09-28 08:41:50 -07:00
/* start over with clean itearator */
2017-07-17 02:04:29 -07:00
const Eolian_Implement * imp ;
Eina_Iterator * itr = eolian_class_implements_get ( cl ) ;
2016-09-28 08:41:50 -07:00
EINA_ITERATOR_FOREACH ( itr , imp )
{
const Eolian_Class * icl = eolian_implement_class_get ( imp ) ;
Eolian_Function_Type ftype ;
const Eolian_Function * fid = eolian_implement_function_get ( imp , & ftype ) ;
2019-08-16 07:32:13 -07:00
if ( eolian_function_is_static ( fid ) ) continue ;
2019-02-09 09:45:27 -08:00
2019-02-15 08:15:36 -08:00
if ( ! eina_strbuf_length_get ( ops ) )
eina_strbuf_append_printf ( ops , " EFL_OPS_DEFINE(ops, \n " ) ;
2016-09-28 08:41:50 -07:00
2016-12-27 08:16:17 -08:00
Eina_Bool found_get = ! ! eina_hash_find ( _funcs_params_init_get , & imp ) ;
Eina_Bool found_set = ! ! eina_hash_find ( _funcs_params_init_set , & imp ) ;
2016-09-28 08:41:50 -07:00
char * ocnamel = NULL ;
2016-09-29 08:19:30 -07:00
if ( cl ! = icl )
2016-09-30 05:22:48 -07:00
eo_gen_class_names_get ( icl , NULL , NULL , & ocnamel ) ;
2016-09-28 08:41:50 -07:00
switch ( ftype )
{
case EOLIAN_PROP_GET :
2019-02-15 08:15:36 -08:00
_gen_opfunc ( fid , EOLIAN_PROP_GET , ops , imp , found_get , cnamel , ocnamel ) ;
_gen_reflop ( fid , refls , cnamel , refh ) ;
2016-09-28 08:41:50 -07:00
break ;
case EOLIAN_PROP_SET :
2019-02-15 08:15:36 -08:00
_gen_opfunc ( fid , EOLIAN_PROP_SET , ops , imp , found_set , cnamel , ocnamel ) ;
_gen_reflop ( fid , refls , cnamel , refh ) ;
2016-09-28 08:41:50 -07:00
break ;
case EOLIAN_PROPERTY :
2019-02-15 08:15:36 -08:00
_gen_opfunc ( fid , EOLIAN_PROP_SET , ops , imp , found_set , cnamel , ocnamel ) ;
_gen_opfunc ( fid , EOLIAN_PROP_GET , ops , imp , found_get , cnamel , ocnamel ) ;
_gen_reflop ( fid , refls , cnamel , refh ) ;
2016-09-28 08:41:50 -07:00
break ;
default :
2019-02-15 08:15:36 -08:00
_gen_opfunc ( fid , EOLIAN_METHOD , ops , imp , found_get , cnamel , ocnamel ) ;
2016-09-28 08:41:50 -07:00
break ;
}
free ( ocnamel ) ;
}
2016-09-30 04:25:41 -07:00
eina_iterator_free ( itr ) ;
2016-09-28 08:41:50 -07:00
if ( eina_strbuf_length_get ( ops ) )
{
2017-04-13 06:56:15 -07:00
/* make sure the extras are defined */
eina_strbuf_append_printf ( buf , " #ifndef %s_EXTRA_OPS \n " , cnameu ) ;
eina_strbuf_append_printf ( buf , " #define %s_EXTRA_OPS \n " , cnameu ) ;
eina_strbuf_append ( buf , " #endif \n \n " ) ;
eina_strbuf_append_printf ( ops , " %s_EXTRA_OPS \n ); \n " , cnameu ) ;
2016-09-28 08:41:50 -07:00
eina_strbuf_append ( buf , eina_strbuf_string_get ( ops ) ) ;
2017-04-13 06:56:15 -07:00
eina_strbuf_append ( buf , " opsp = &ops; \n \n " ) ;
}
else
{
/* no predefined, but if custom ones are required define it anyway */
eina_strbuf_append_printf ( buf , " #ifdef %s_EXTRA_OPS \n " , cnameu ) ;
eina_strbuf_append_printf ( buf , " EFL_OPS_DEFINE(ops, %s_EXTRA_OPS); \n " , cnameu ) ;
eina_strbuf_append ( buf , " opsp = &ops; \n " ) ;
eina_strbuf_append ( buf , " #endif \n \n " ) ;
2016-09-28 08:41:50 -07:00
}
2017-04-13 06:56:15 -07:00
2019-02-15 08:15:36 -08:00
if ( eina_strbuf_length_get ( refls ) )
{
eina_strbuf_append ( buf , " static const Efl_Object_Property_Reflection refl_table[] = { \n " ) ;
eina_strbuf_append_buffer ( buf , refls ) ;
eina_strbuf_append ( buf , " }; \n " ) ;
eina_strbuf_append ( buf , " static const Efl_Object_Property_Reflection_Ops rops = { \n " ) ;
eina_strbuf_append ( buf , " refl_table, EINA_C_ARRAY_LENGTH(refl_table) \n " ) ;
eina_strbuf_append ( buf , " }; \n " ) ;
eina_strbuf_append ( buf , " ropsp = &rops; \n \n " ) ;
}
eina_strbuf_append ( buf , " return efl_class_functions_set(klass, opsp, ropsp); \n " ) ;
2016-09-28 08:41:50 -07:00
eina_strbuf_free ( ops ) ;
2019-03-12 08:31:51 -07:00
eina_strbuf_free ( refls ) ;
2016-09-28 08:41:50 -07:00
2016-09-29 07:20:51 -07:00
eina_strbuf_append ( buf , " } \n \n " ) ;
2016-09-28 08:41:50 -07:00
2017-04-13 06:56:15 -07:00
free ( cnameu ) ;
2016-09-29 08:19:30 -07:00
free ( cnamel ) ;
2016-09-28 08:41:50 -07:00
}
2016-09-22 06:58:06 -07:00
void
2019-03-08 06:58:52 -08:00
eo_gen_source_gen ( const Eolian_Class * cl , Eina_Strbuf * buf )
2016-09-22 06:58:06 -07:00
{
if ( ! cl )
return ;
2016-09-22 07:59:28 -07:00
2016-12-27 08:16:17 -08:00
_funcs_params_init_get = eina_hash_pointer_new ( NULL ) ;
_funcs_params_init_set = eina_hash_pointer_new ( NULL ) ;
2016-09-23 08:49:44 -07:00
2016-12-07 04:19:48 -08:00
char * cnamel = NULL ;
eo_gen_class_names_get ( cl , NULL , NULL , & cnamel ) ;
2016-09-29 07:20:51 -07:00
2016-09-22 07:59:28 -07:00
/* event section, they come first */
{
Eina_Iterator * itr = eolian_class_events_get ( cl ) ;
Eolian_Event * ev ;
EINA_ITERATOR_FOREACH ( itr , ev )
{
2019-05-16 06:57:39 -07:00
Eina_Stringshare * evn = eolian_event_c_macro_get ( ev ) ;
2016-10-20 07:48:41 -07:00
eina_strbuf_append ( buf , " EWAPI const Efl_Event_Description _ " ) ;
2016-09-22 07:59:28 -07:00
eina_strbuf_append ( buf , evn ) ;
eina_strbuf_append ( buf , " = \n EFL_EVENT_DESCRIPTION " ) ;
if ( eolian_event_is_hot ( ev ) )
eina_strbuf_append ( buf , " _HOT " ) ;
if ( eolian_event_is_restart ( ev ) )
eina_strbuf_append ( buf , " _RESTART " ) ;
eina_strbuf_append_printf ( buf , " ( \" %s \" ); \n " , eolian_event_name_get ( ev ) ) ;
eina_stringshare_del ( evn ) ;
}
eina_iterator_free ( itr ) ;
}
2016-09-23 08:49:44 -07:00
2019-02-15 08:15:36 -08:00
/* Eolian_Function -> Eolian_Function_Type
* maps which parts of which functions are qualified for reflection
*/
Eina_Hash * refh = eina_hash_pointer_new ( NULL ) ;
2016-09-23 08:49:44 -07:00
/* method section */
{
Eina_Iterator * itr = eolian_class_implements_get ( cl ) ;
const Eolian_Implement * imp ;
EINA_ITERATOR_FOREACH ( itr , imp )
{
Eolian_Function_Type ftype = EOLIAN_UNRESOLVED ;
const Eolian_Function * fid = eolian_implement_function_get ( imp , & ftype ) ;
switch ( ftype )
{
case EOLIAN_PROP_GET :
case EOLIAN_PROP_SET :
2019-03-08 06:58:52 -08:00
_gen_func ( cl , fid , ftype , buf , imp , refh ) ;
2016-09-23 08:49:44 -07:00
break ;
case EOLIAN_PROPERTY :
2019-03-08 06:58:52 -08:00
_gen_func ( cl , fid , EOLIAN_PROP_SET , buf , imp , refh ) ;
_gen_func ( cl , fid , EOLIAN_PROP_GET , buf , imp , refh ) ;
2016-09-23 08:49:44 -07:00
break ;
default :
2019-03-08 06:58:52 -08:00
_gen_func ( cl , fid , EOLIAN_METHOD , buf , imp , refh ) ;
2016-09-23 08:49:44 -07:00
}
}
eina_iterator_free ( itr ) ;
}
2016-09-29 07:20:51 -07:00
/* class initializer - contains method defs */
2019-02-15 08:15:36 -08:00
_gen_initializer ( cl , buf , refh ) ;
eina_hash_free ( refh ) ;
2016-09-28 08:41:50 -07:00
2016-09-29 07:20:51 -07:00
/* class description */
eina_strbuf_append ( buf , " static const Efl_Class_Description _ " ) ;
eina_strbuf_append ( buf , cnamel ) ;
eina_strbuf_append ( buf , " _class_desc = { \n "
" EO_VERSION, \n " ) ;
2018-03-12 08:03:37 -07:00
eina_strbuf_append_printf ( buf , " \" %s \" , \n " , eolian_class_name_get ( cl ) ) ;
2016-09-29 07:20:51 -07:00
2016-09-30 05:07:16 -07:00
switch ( eolian_class_type_get ( cl ) )
{
case EOLIAN_CLASS_ABSTRACT :
eina_strbuf_append ( buf , " EFL_CLASS_TYPE_REGULAR_NO_INSTANT, \n " ) ;
break ;
case EOLIAN_CLASS_MIXIN :
eina_strbuf_append ( buf , " EFL_CLASS_TYPE_MIXIN, \n " ) ;
break ;
case EOLIAN_CLASS_INTERFACE :
eina_strbuf_append ( buf , " EFL_CLASS_TYPE_INTERFACE, \n " ) ;
break ;
default :
eina_strbuf_append ( buf , " EFL_CLASS_TYPE_REGULAR, \n " ) ;
break ;
}
2016-10-13 06:03:50 -07:00
Eina_Stringshare * dt = eolian_class_c_data_type_get ( cl ) ;
if ( ! strcmp ( dt , " void " ) )
2016-09-29 07:20:51 -07:00
eina_strbuf_append ( buf , " 0, \n " ) ;
else
2016-10-13 06:03:50 -07:00
eina_strbuf_append_printf ( buf , " sizeof(%s), \n " , dt ) ;
eina_stringshare_del ( dt ) ;
2016-09-29 07:20:51 -07:00
2017-07-17 02:04:29 -07:00
eina_strbuf_append_printf ( buf , " _%s_class_initializer, \n " , cnamel ) ;
2016-09-29 07:20:51 -07:00
if ( eolian_class_ctor_enable_get ( cl ) )
eina_strbuf_append_printf ( buf , " _%s_class_constructor, \n " , cnamel ) ;
else
eina_strbuf_append ( buf , " NULL, \n " ) ;
if ( eolian_class_dtor_enable_get ( cl ) )
eina_strbuf_append_printf ( buf , " _%s_class_destructor \n " , cnamel ) ;
else
eina_strbuf_append ( buf , " NULL \n " ) ;
2016-09-30 04:40:39 -07:00
eina_strbuf_append ( buf , " }; \n \n " ) ;
2016-09-29 07:20:51 -07:00
/* class def */
eina_strbuf_append ( buf , " EFL_DEFINE_CLASS( " ) ;
Eina_Stringshare * cgfunc = eolian_class_c_get_function_name_get ( cl ) ;
eina_strbuf_append ( buf , cgfunc ) ;
eina_stringshare_del ( cgfunc ) ;
eina_strbuf_append_printf ( buf , " , &_%s_class_desc " , cnamel ) ;
/* inherits in EFL_DEFINE_CLASS */
{
2018-11-22 07:21:52 -08:00
const Eolian_Class * icl = eolian_class_parent_get ( cl ) ;
2016-09-30 05:15:07 -07:00
/* no inherits, NULL parent */
2018-11-22 07:21:52 -08:00
if ( ! icl )
2016-09-30 05:15:07 -07:00
eina_strbuf_append ( buf , " , NULL " ) ;
2018-11-22 07:21:52 -08:00
else
{
2019-05-16 06:31:37 -07:00
Eina_Stringshare * mname = eolian_class_c_macro_get ( icl ) ;
2018-11-22 07:21:52 -08:00
eina_strbuf_append_printf ( buf , " , %s " , mname ) ;
eina_stringshare_del ( mname ) ;
}
Eina_Iterator * itr = eolian_class_extensions_get ( cl ) ;
2017-10-25 07:23:57 -07:00
EINA_ITERATOR_FOREACH ( itr , icl )
2016-09-29 07:20:51 -07:00
{
2019-05-16 06:31:37 -07:00
Eina_Stringshare * mname = eolian_class_c_macro_get ( icl ) ;
2016-10-12 06:05:46 -07:00
eina_strbuf_append_printf ( buf , " , %s " , mname ) ;
eina_stringshare_del ( mname ) ;
2016-09-29 07:20:51 -07:00
}
eina_iterator_free ( itr ) ;
}
/* terminate inherits */
eina_strbuf_append ( buf , " , NULL); \n " ) ;
/* and we're done */
free ( cnamel ) ;
2016-12-27 08:16:17 -08:00
eina_hash_free ( _funcs_params_init_get ) ;
eina_hash_free ( _funcs_params_init_set ) ;
2016-09-22 06:58:06 -07:00
}
2016-10-05 05:45:27 -07:00
2016-10-06 07:13:39 -07:00
static void
2018-01-16 07:36:45 -08:00
_gen_params ( const Eolian_Function * fid , Eolian_Function_Type ftype ,
Eina_Bool var_as_ret , Eina_Strbuf * params , Eina_Strbuf * params_full )
2016-10-06 07:13:39 -07:00
{
2016-10-06 07:33:45 -07:00
Eina_Bool is_prop = ( ftype = = EOLIAN_PROP_GET | | ftype = = EOLIAN_PROP_SET ) ;
/* property keys */
{
Eina_Iterator * itr = eolian_property_keys_get ( fid , ftype ) ;
Eolian_Function_Parameter * pr ;
EINA_ITERATOR_FOREACH ( itr , pr )
{
const char * prn = eolian_parameter_name_get ( pr ) ;
2019-09-05 06:14:39 -07:00
Eina_Stringshare * ptn = eolian_parameter_c_type_get ( pr , EINA_FALSE ) ;
2016-10-06 07:33:45 -07:00
eina_strbuf_append ( params , " , " ) ;
eina_strbuf_append ( params , prn ) ;
eina_strbuf_append_printf ( params_full , " , %s " , ptn ) ;
2016-10-14 06:31:23 -07:00
if ( ptn [ strlen ( ptn ) - 1 ] ! = ' * ' )
2016-10-06 07:33:45 -07:00
eina_strbuf_append_char ( params_full , ' ' ) ;
eina_strbuf_append ( params_full , prn ) ;
eina_stringshare_del ( ptn ) ;
}
eina_iterator_free ( itr ) ;
}
/* property values or method params if applicable */
if ( ! var_as_ret )
{
Eina_Iterator * itr ;
if ( is_prop )
itr = eolian_property_values_get ( fid , ftype ) ;
else
itr = eolian_function_parameters_get ( fid ) ;
Eolian_Function_Parameter * pr ;
EINA_ITERATOR_FOREACH ( itr , pr )
{
Eolian_Parameter_Dir pd = eolian_parameter_direction_get ( pr ) ;
const char * prn = eolian_parameter_name_get ( pr ) ;
const Eolian_Type * pt = eolian_parameter_type_get ( pr ) ;
2018-01-12 08:52:44 -08:00
const Eolian_Typedecl * ptd = eolian_type_typedecl_get ( pt ) ;
2019-09-05 06:14:39 -07:00
Eina_Stringshare * ptn = eolian_parameter_c_type_get ( pr , EINA_FALSE ) ;
2016-10-06 07:33:45 -07:00
2017-04-07 09:54:55 -07:00
if ( ptd & & eolian_typedecl_type_get ( ptd ) = = EOLIAN_TYPEDECL_FUNCTION_POINTER )
{
eina_strbuf_append_printf ( params , " , %s_data, %s, %s_free_cb " , prn , prn , prn ) ;
eina_strbuf_append_printf ( params_full , " , void *%s_data, %s %s, Eina_Free_Cb %s_free_cb " , prn , ptn , prn , prn ) ;
eina_stringshare_del ( ptn ) ;
continue ;
}
2016-10-14 06:31:23 -07:00
Eina_Bool had_star = ptn [ strlen ( ptn ) - 1 ] = = ' * ' ;
2016-10-06 07:33:45 -07:00
const char * add_star = _get_add_star ( ftype , pd ) ;
eina_strbuf_append ( params , " , " ) ;
eina_strbuf_append ( params , prn ) ;
eina_strbuf_append ( params_full , " , " ) ;
eina_strbuf_append ( params_full , ptn ) ;
if ( ! had_star )
eina_strbuf_append_char ( params_full , ' ' ) ;
eina_strbuf_append ( params_full , add_star ) ;
eina_strbuf_append ( params_full , prn ) ;
eina_stringshare_del ( ptn ) ;
}
eina_iterator_free ( itr ) ;
}
2016-10-06 07:13:39 -07:00
}
2016-10-06 05:46:07 -07:00
static void
2018-01-16 07:36:45 -08:00
_gen_proto ( const Eolian_Class * cl , const Eolian_Function * fid ,
Eolian_Function_Type ftype , Eina_Strbuf * buf ,
const Eolian_Implement * impl , const char * dtype , const char * cnamel )
2016-10-06 05:46:07 -07:00
{
2016-10-06 07:13:39 -07:00
Eina_Bool impl_same_class = ( eolian_implement_class_get ( impl ) = = cl ) ;
2017-01-16 06:51:11 -08:00
if ( impl_same_class & & eolian_implement_is_pure_virtual ( impl , ftype ) )
2016-10-06 07:13:39 -07:00
return ;
char * ocnamel = NULL ;
if ( ! impl_same_class )
eo_gen_class_names_get ( eolian_implement_class_get ( impl ) , NULL , NULL , & ocnamel ) ;
2018-11-06 10:00:39 -08:00
char fname [ 256 + 128 ] , iname [ 256 ] ;
2016-10-06 07:33:45 -07:00
if ( ! impl_same_class )
2016-10-06 07:13:39 -07:00
snprintf ( iname , sizeof ( iname ) , " %s_%s " , cnamel , ocnamel ) ;
else
snprintf ( iname , sizeof ( iname ) , " %s " , cnamel ) ;
snprintf ( fname , sizeof ( fname ) , " _%s_%s%s " , iname , eolian_function_name_get ( fid ) ,
( ftype = = EOLIAN_PROP_GET )
? " _get " : ( ( ftype = = EOLIAN_PROP_SET ) ? " _set " : " " ) ) ;
if ( _function_exists ( fname , buf ) )
{
free ( ocnamel ) ;
return ;
}
2016-10-06 07:33:45 -07:00
printf ( " generating function %s... \n " , fname ) ;
2016-10-06 07:13:39 -07:00
Eina_Bool var_as_ret = EINA_FALSE ;
const Eolian_Type * rtp = eolian_function_return_type_get ( fid , ftype ) ;
2019-09-05 06:14:39 -07:00
Eina_Stringshare * rtpn = NULL ;
2016-10-06 07:13:39 -07:00
if ( ( ftype = = EOLIAN_PROP_GET ) & & ! rtp )
{
void * d1 , * d2 ;
Eina_Iterator * itr = eolian_property_values_get ( fid , ftype ) ;
if ( eina_iterator_next ( itr , & d1 ) & & ! eina_iterator_next ( itr , & d2 ) )
{
Eolian_Function_Parameter * pr = d1 ;
rtp = eolian_parameter_type_get ( pr ) ;
2019-09-05 06:14:39 -07:00
rtpn = eolian_parameter_c_type_get ( pr , EINA_FALSE ) ;
2016-10-06 07:13:39 -07:00
var_as_ret = EINA_TRUE ;
}
eina_iterator_free ( itr ) ;
}
eina_strbuf_append ( buf , " EOLIAN static " ) ;
if ( rtp )
{
2019-09-05 06:14:39 -07:00
if ( ! rtpn )
rtpn = eolian_function_return_c_type_get ( fid , ftype ) ;
2016-10-06 07:13:39 -07:00
eina_strbuf_append ( buf , rtpn ) ;
eina_stringshare_del ( rtpn ) ;
}
else
eina_strbuf_append ( buf , " void " ) ;
eina_strbuf_append_printf ( buf , " \n %s( " , fname ) ;
2018-04-17 11:09:44 -07:00
if ( ( ftype = = EOLIAN_PROP_GET ) | | eolian_function_object_is_const ( fid ) )
2016-10-06 07:13:39 -07:00
eina_strbuf_append ( buf , " const " ) ;
eina_strbuf_append ( buf , " Eo *obj, " ) ;
2016-10-13 06:03:50 -07:00
if ( strcmp ( dtype , " void " ) )
2016-10-06 07:13:39 -07:00
eina_strbuf_append_printf ( buf , " %s *pd " , dtype ) ;
else
eina_strbuf_append ( buf , " void *pd EINA_UNUSED " ) ;
/* gen params here */
Eina_Strbuf * params = eina_strbuf_new ( ) ;
Eina_Strbuf * params_full = eina_strbuf_new ( ) ;
2018-01-16 07:36:45 -08:00
_gen_params ( fid , ftype , var_as_ret , params , params_full ) ;
2016-10-06 07:13:39 -07:00
if ( eina_strbuf_length_get ( params_full ) )
2016-10-06 07:33:45 -07:00
eina_strbuf_append ( buf , eina_strbuf_string_get ( params_full ) ) ;
2016-10-06 07:13:39 -07:00
eina_strbuf_append ( buf , " ) \n { \n " ) ;
const char * efname = eolian_function_name_get ( fid ) ;
if ( strlen ( efname ) > = ( sizeof ( " destructor " ) - 1 ) & & ! impl_same_class )
if ( ! strcmp ( efname + strlen ( efname ) - sizeof ( " destructor " ) + 1 , " destructor " ) )
{
2019-03-08 06:58:52 -08:00
Eina_Stringshare * fcn = eolian_function_full_c_name_get ( fid , ftype ) ;
2019-05-16 06:31:37 -07:00
Eina_Stringshare * mname = eolian_class_c_macro_get ( cl ) ;
2016-10-06 07:13:39 -07:00
eina_strbuf_append ( buf , " " ) ;
eina_strbuf_append ( buf , fcn ) ;
eina_stringshare_del ( fcn ) ;
2016-10-12 06:05:46 -07:00
eina_strbuf_append_printf ( buf , " (efl_super(obj, %s) " , mname ) ;
eina_stringshare_del ( mname ) ;
2016-10-06 07:13:39 -07:00
if ( eina_strbuf_length_get ( params ) )
2016-10-06 07:33:45 -07:00
eina_strbuf_append ( buf , eina_strbuf_string_get ( params ) ) ;
2016-10-06 07:13:39 -07:00
eina_strbuf_append ( buf , " ); \n " ) ;
}
eina_strbuf_append ( buf , " \n } \n \n " ) ;
eina_strbuf_free ( params_full ) ;
eina_strbuf_free ( params ) ;
free ( ocnamel ) ;
2016-10-06 05:46:07 -07:00
}
2016-10-05 05:45:27 -07:00
void
2018-01-16 07:36:45 -08:00
eo_gen_impl_gen ( const Eolian_Class * cl , Eina_Strbuf * buf )
2016-10-05 05:45:27 -07:00
{
if ( ! cl )
return ;
2016-10-05 07:32:17 -07:00
2016-10-12 06:05:46 -07:00
char * cname = NULL , * cnamel = NULL ;
eo_gen_class_names_get ( cl , & cname , NULL , & cnamel ) ;
2016-10-05 07:32:17 -07:00
Eina_Strbuf * beg = eina_strbuf_new ( ) ;
if ( ! _type_exists ( " EFL_BETA_API_SUPPORT " , buf ) )
{
printf ( " generating EFL_BETA_API_SUPPORT... \n " ) ;
eina_strbuf_append ( beg , " #define EFL_BETA_API_SUPPORT \n " ) ;
}
if ( ! _type_exists ( " <Eo.h> " , buf ) )
{
printf ( " generating includes for <Eo.h> and \" %s.eo.h \" ... \n " , cnamel ) ;
eina_strbuf_append ( beg , " #include <Eo.h> \n " ) ;
eina_strbuf_append_printf ( beg , " #include \" %s.eo.h \" \n \n " , cnamel ) ;
}
/* determine data type name */
2016-10-13 06:03:50 -07:00
Eina_Stringshare * dt = eolian_class_c_data_type_get ( cl ) ;
2016-10-05 07:32:17 -07:00
/* generate data type struct */
2016-10-13 06:03:50 -07:00
if ( strcmp ( dt , " void " ) & & ! _type_exists ( dt , buf ) )
2016-10-05 07:32:17 -07:00
{
2016-10-13 06:03:50 -07:00
printf ( " generating data type structure %s... \n " , dt ) ;
eina_strbuf_append_printf ( beg , " typedef struct \n { \n \n } %s; \n \n " , dt ) ;
2016-10-05 07:32:17 -07:00
}
if ( eina_strbuf_length_get ( beg ) )
eina_strbuf_prepend ( buf , eina_strbuf_string_get ( beg ) ) ;
eina_strbuf_free ( beg ) ;
2016-10-06 05:46:07 -07:00
/* method section */
{
Eina_Iterator * itr = eolian_class_implements_get ( cl ) ;
const Eolian_Implement * imp ;
EINA_ITERATOR_FOREACH ( itr , imp )
{
Eolian_Function_Type ftype = EOLIAN_UNRESOLVED ;
const Eolian_Function * fid = eolian_implement_function_get ( imp , & ftype ) ;
switch ( ftype )
{
case EOLIAN_PROP_GET :
case EOLIAN_PROP_SET :
2018-01-16 07:36:45 -08:00
_gen_proto ( cl , fid , ftype , buf , imp , dt , cnamel ) ;
2016-10-06 05:46:07 -07:00
break ;
case EOLIAN_PROPERTY :
2018-01-16 07:36:45 -08:00
_gen_proto ( cl , fid , EOLIAN_PROP_SET , buf , imp , dt , cnamel ) ;
_gen_proto ( cl , fid , EOLIAN_PROP_GET , buf , imp , dt , cnamel ) ;
2016-10-06 05:46:07 -07:00
break ;
default :
2018-01-16 07:36:45 -08:00
_gen_proto ( cl , fid , EOLIAN_METHOD , buf , imp , dt , cnamel ) ;
2016-10-06 05:46:07 -07:00
}
}
eina_iterator_free ( itr ) ;
}
2016-10-13 06:03:50 -07:00
/* free the data type */
eina_stringshare_del ( dt ) ;
2016-10-06 05:46:07 -07:00
if ( eolian_class_ctor_enable_get ( cl ) )
{
char fname [ 128 ] ;
snprintf ( fname , sizeof ( fname ) , " _%s_class_constructor " , cnamel ) ;
if ( ! _function_exists ( fname , buf ) )
{
printf ( " generating function %s... \n " , fname ) ;
eina_strbuf_append_printf ( buf ,
" EOLIAN static void \n "
" _%s_class_constructor(Efl_Class *klass) \n "
2016-10-06 05:56:49 -07:00
" { \n \n "
2016-10-06 05:46:07 -07:00
" } \n \n " , cnamel ) ;
}
}
if ( eolian_class_dtor_enable_get ( cl ) )
{
char fname [ 128 ] ;
snprintf ( fname , sizeof ( fname ) , " _%s_class_destructor " , cnamel ) ;
if ( ! _function_exists ( fname , buf ) )
{
printf ( " generating function %s... \n " , fname ) ;
eina_strbuf_append_printf ( buf ,
" EOLIAN static void \n "
" _%s_class_destructor(Efl_Class *klass) \n "
2016-10-06 05:56:49 -07:00
" { \n \n "
2016-10-06 05:46:07 -07:00
" } \n \n " , cnamel ) ;
}
}
printf ( " removing includes for \" %s.eo.c \" \n " , cnamel ) ;
char ibuf [ 512 ] ;
snprintf ( ibuf , sizeof ( ibuf ) , " \n #include \" %s.eo.c \" \n " , cnamel ) ;
eina_strbuf_replace_all ( buf , ibuf , " \n " ) ;
printf ( " generating include for \" %s.eo.c \" \n " , cnamel ) ;
eina_strbuf_append_printf ( buf , " #include \" %s.eo.c \" \n " , cnamel ) ;
2016-10-05 07:32:17 -07:00
free ( cname ) ;
free ( cnamel ) ;
2016-10-05 05:45:27 -07:00
}