2017-10-25 03:25:14 -07:00
# include "config.h"
# include "Efl.h"
2017-11-23 21:56:10 -08:00
# define ERR(...) EINA_LOG_DOM_ERR(EINA_LOG_DOMAIN_DEFAULT, __VA_ARGS__)
2017-12-11 18:30:13 -08:00
# define DBG(...) EINA_LOG_DOM_DBG(EINA_LOG_DOMAIN_DEFAULT, __VA_ARGS__)
2017-11-23 21:56:10 -08:00
2017-11-27 19:12:08 -08:00
typedef enum _Format_Type
{
FORMAT_TYPE_INVALID ,
FORMAT_TYPE_DOUBLE ,
2017-12-11 18:30:13 -08:00
FORMAT_TYPE_INT ,
FORMAT_TYPE_STRING ,
2018-02-09 23:26:15 -08:00
FORMAT_TYPE_STATIC
2017-11-27 19:12:08 -08:00
} Format_Type ;
2017-11-28 00:05:31 -08:00
typedef struct
{
const char * template ;
Format_Type format_type ;
} Efl_Ui_Format_Data ;
2017-11-23 21:56:10 -08:00
static Eina_Bool
_is_valid_digit ( char x )
{
return ( ( x > = ' 0 ' & & x < = ' 9 ' ) | | ( x = = ' . ' ) ) ? EINA_TRUE : EINA_FALSE ;
}
2017-11-27 19:12:08 -08:00
static Format_Type
2017-11-23 21:56:10 -08:00
_format_string_check ( const char * fmt )
{
2018-02-09 23:26:15 -08:00
const char * itr ;
2017-11-23 21:56:10 -08:00
Eina_Bool found = EINA_FALSE ;
2018-02-09 23:26:15 -08:00
Format_Type ret_type = FORMAT_TYPE_STATIC ;
2017-11-23 21:56:10 -08:00
2018-02-09 23:26:15 -08:00
for ( itr = fmt ; * itr ; itr + + )
2017-11-23 21:56:10 -08:00
{
2018-02-09 23:26:15 -08:00
if ( itr [ 0 ] ! = ' % ' ) continue ;
if ( itr [ 1 ] = = ' % ' )
2017-11-23 21:56:10 -08:00
{
2018-02-09 23:26:15 -08:00
itr + + ;
2019-02-01 00:13:39 -08:00
if ( ret_type = = FORMAT_TYPE_STATIC )
ret_type = FORMAT_TYPE_STRING ;
2018-02-09 23:26:15 -08:00
continue ;
2017-11-23 21:56:10 -08:00
}
2018-02-09 23:26:15 -08:00
if ( ! found )
2017-11-23 21:56:10 -08:00
{
found = EINA_TRUE ;
2018-02-09 23:26:15 -08:00
for ( itr + + ; * itr ; itr + + )
2017-11-23 21:56:10 -08:00
{
2017-12-11 18:30:13 -08:00
// FIXME: This does not properly support int64 or unsigned.
2017-11-23 21:56:10 -08:00
if ( ( * itr = = ' d ' ) | | ( * itr = = ' u ' ) | | ( * itr = = ' i ' ) | |
( * itr = = ' o ' ) | | ( * itr = = ' x ' ) | | ( * itr = = ' X ' ) )
{
2017-11-27 19:12:08 -08:00
ret_type = FORMAT_TYPE_INT ;
2017-11-23 21:56:10 -08:00
break ;
}
else if ( ( * itr = = ' f ' ) | | ( * itr = = ' F ' ) )
{
2017-11-27 19:12:08 -08:00
ret_type = FORMAT_TYPE_DOUBLE ;
2017-11-23 21:56:10 -08:00
break ;
}
2017-12-11 18:30:13 -08:00
else if ( * itr = = ' s ' )
{
ret_type = FORMAT_TYPE_STRING ;
break ;
}
2017-11-23 21:56:10 -08:00
else if ( _is_valid_digit ( * itr ) )
{
continue ;
}
else
{
2019-02-01 00:13:39 -08:00
ERR ( " Format string '%s' has unknown format element '%c' in format. It must have one format element of type 's', 'f', 'F', 'd', 'u', 'i', 'o', 'x' or 'X' " , fmt , * itr ) ;
found = EINA_FALSE ;
2017-11-27 19:12:08 -08:00
break ;
2017-11-23 21:56:10 -08:00
}
}
2018-02-09 23:26:15 -08:00
if ( ! ( * itr ) ) break ;
}
else
{
ret_type = FORMAT_TYPE_INVALID ;
break ;
2017-11-23 21:56:10 -08:00
}
}
2018-02-09 23:26:15 -08:00
if ( ret_type = = FORMAT_TYPE_INVALID )
{
ERR ( " Format string '%s' is invalid. It must have one and only one format element of type 's', 'f', 'F', 'd', 'u', 'i', 'o', 'x' or 'X' " , fmt ) ;
}
2017-11-23 21:56:10 -08:00
return ret_type ;
}
2017-10-25 03:25:14 -07:00
static void
_default_format_cb ( void * data , Eina_Strbuf * str , const Eina_Value value )
{
Efl_Ui_Format_Data * sd = data ;
2017-12-11 18:30:13 -08:00
Eina_Value copy ;
2017-11-23 21:56:10 -08:00
2017-12-11 18:30:13 -08:00
if ( sd - > format_type = = FORMAT_TYPE_DOUBLE )
2017-11-23 21:56:10 -08:00
{
2017-12-11 18:30:13 -08:00
double v = 0.0 ;
eina_value_setup ( & copy , EINA_VALUE_TYPE_DOUBLE ) ;
eina_value_convert ( & value , & copy ) ;
eina_value_get ( & copy , & v ) ;
2017-10-25 03:25:14 -07:00
eina_strbuf_append_printf ( str , sd - > template , v ) ;
2017-12-11 18:30:13 -08:00
eina_value_flush ( & copy ) ;
2017-10-25 03:25:14 -07:00
}
2017-12-11 18:30:13 -08:00
else if ( sd - > format_type = = FORMAT_TYPE_INT )
2017-10-25 03:25:14 -07:00
{
2017-12-11 18:30:13 -08:00
int v = 0 ;
eina_value_setup ( & copy , EINA_VALUE_TYPE_INT ) ;
eina_value_convert ( & value , & copy ) ;
eina_value_get ( & copy , & v ) ;
2017-10-25 03:25:14 -07:00
eina_strbuf_append_printf ( str , sd - > template , v ) ;
2017-12-11 18:30:13 -08:00
eina_value_flush ( & copy ) ;
2017-10-25 03:25:14 -07:00
}
2017-12-11 18:30:13 -08:00
else if ( sd - > format_type = = FORMAT_TYPE_STRING )
2017-11-27 19:12:08 -08:00
{
2017-12-11 18:30:13 -08:00
char * v = eina_value_to_string ( & value ) ;
eina_strbuf_append_printf ( str , sd - > template , v ) ;
free ( v ) ;
2017-11-27 19:12:08 -08:00
}
2018-02-09 23:26:15 -08:00
else if ( sd - > format_type = = FORMAT_TYPE_STATIC )
{
2019-02-01 00:13:39 -08:00
eina_strbuf_append ( str , sd - > template ) ;
2018-02-09 23:26:15 -08:00
}
2017-10-25 03:25:14 -07:00
else
{
2017-12-11 18:30:13 -08:00
// Error: Discard format string and just print value.
DBG ( " Could not guess value type in format string: '%s' " , sd - > template ) ;
2017-10-25 03:25:14 -07:00
char * v = eina_value_to_string ( & value ) ;
2017-12-11 18:30:13 -08:00
eina_strbuf_append ( str , v ) ;
2017-10-25 03:25:14 -07:00
free ( v ) ;
}
}
static void
_default_format_free_cb ( void * data )
{
Efl_Ui_Format_Data * sd = data ;
2017-11-06 20:28:01 -08:00
if ( sd & & sd - > template )
2017-10-25 03:25:14 -07:00
{
eina_stringshare_del ( sd - > template ) ;
sd - > template = NULL ;
}
}
EOLIAN static void
_efl_ui_format_format_string_set ( Eo * obj , Efl_Ui_Format_Data * sd , const char * template )
{
if ( ! template ) return ;
2017-11-28 00:05:31 -08:00
2017-10-25 03:25:14 -07:00
eina_stringshare_replace ( & sd - > template , template ) ;
2017-11-28 00:05:31 -08:00
sd - > format_type = _format_string_check ( sd - > template ) ;
2017-10-25 03:25:14 -07:00
efl_ui_format_cb_set ( obj , sd , _default_format_cb , _default_format_free_cb ) ;
}
EOLIAN static const char *
2018-04-17 11:09:44 -07:00
_efl_ui_format_format_string_get ( const Eo * obj EINA_UNUSED , Efl_Ui_Format_Data * sd )
2017-10-25 03:25:14 -07:00
{
return sd - > template ;
}
# include "interfaces/efl_ui_format.eo.c"