# include <search.h>
#endif
#include <assert.h>
+#include <float.h>
#include <math.h>
#include <limits.h>
#ifdef __GLIBC__
static void FreeDummy( vlc_value_t *p_val ) { (void)p_val; /* unused */ }
static void FreeString( vlc_value_t *p_val ) { free( p_val->psz_string ); }
-static void FreeList( vlc_value_t *p_val )
-{
- int i;
- for( i = 0; i < p_val->p_list->i_count; i++ )
- {
- switch( p_val->p_list->i_type & VLC_VAR_CLASS )
- {
- case VLC_VAR_STRING:
- FreeString( &p_val->p_list->p_values[i] );
- break;
- default:
- break;
- }
- }
-
- if( p_val->p_list->i_count )
- free( p_val->p_list->p_values );
- free( p_val->p_list );
-}
-
static const struct variable_ops_t
void_ops = { NULL, DupDummy, FreeDummy, },
addr_ops = { CmpAddress, DupDummy, FreeDummy, },
p_var->ops = &void_ops;
break;
default:
- assert (0);
+ vlc_assert_unreachable ();
}
if( (i_type & VLC_VAR_DOINHERIT)
p_var->ops->pf_free( &oldval );
break;
case VLC_VAR_GETCHOICES:
- case VLC_VAR_GETLIST:
- p_val->p_list = malloc( sizeof(vlc_list_t) );
- if( p_val2 ) p_val2->p_list = malloc( sizeof(vlc_list_t) );
- if( p_var->choices.i_count )
- {
- p_val->p_list->p_values = malloc( p_var->choices.i_count
- * sizeof(vlc_value_t) );
- if( p_val2 )
- {
- p_val2->p_list->p_values =
- malloc( p_var->choices.i_count * sizeof(vlc_value_t) );
- }
- }
+ p_val->p_list = xmalloc( sizeof(vlc_list_t) );
+ p_val->p_list->p_values =
+ xmalloc( p_var->choices.i_count * sizeof(vlc_value_t) );
p_val->p_list->i_type = p_var->i_type;
p_val->p_list->i_count = p_var->choices.i_count;
if( p_val2 )
{
+ p_val2->p_list = xmalloc( sizeof(vlc_list_t) );
+ p_val2->p_list->p_values =
+ xmalloc( p_var->choices.i_count * sizeof(vlc_value_t) );
p_val2->p_list->i_type = VLC_VAR_STRING;
p_val2->p_list->i_count = p_var->choices.i_count;
}
p_var = Lookup( p_this, psz_name );
if( p_var != NULL )
+ {
i_type = p_var->i_type;
-
+ if( p_var->choices.i_count > 0 )
+ i_type |= VLC_VAR_HASCHOICE;
+ }
vlc_mutex_unlock( &p_priv->var_lock );
return i_type;
if( b_found_similar )
fprintf( stderr, "Calling var_DelCallback for '%s' with the same "
"function but not the same data.", psz_name );
- assert( 0 );
+ vlc_assert_unreachable();
#endif
vlc_mutex_unlock( &p_priv->var_lock );
return VLC_EGENERIC;
p_val->b_bool = config_GetInt( p_this, psz_name );
break;
default:
- assert(0);
+ vlc_assert_unreachable();
case VLC_VAR_ADDRESS:
return VLC_ENOOBJ;
}
unsigned d = strtol(*next ? &next[1] : "0", NULL, 0);
if (*next == '.') {
- /* Interpret as a float number */
- double r = us_atof(tmp);
- double c = ceil(r);
- if (c >= UINT_MAX)
- goto error;
- unsigned m = c;
- if (m > 0) {
- d = UINT_MAX / m;
- n = r * d;
- } else {
- n = 0;
- d = 0;
- }
+ /* Interpret as a (finite positive) float number */
+ const int ubits = CHAR_BIT * sizeof (unsigned);
+ int exp;
+ double f = frexp(us_atof(tmp), &exp);
+
+ if (!isgreaterequal(f, 0.))
+ goto error; /* negative or not a number */
+
+ if (exp <= 1 - ubits) {
+ n = 0; /* too small */
+ d = 1;
+ } else if (exp <= 0) {
+ n = floor(scalbn(f, ubits - 1 + exp));
+#if (FLT_RADIX != 2)
+# error Floating point configuration not supported.
+#endif
+ d = 1u << (ubits - 1);
+ } else if (exp <= ubits) {
+ n = floor(scalbn(f, ubits));
+ d = 1u << (ubits - exp);
+ } else
+ goto error; /* too big */
} else if ( *next == '\0' ) {
/* plain integer given */
*num = n;
*/
void var_FreeList( vlc_value_t *p_val, vlc_value_t *p_val2 )
{
- FreeList( p_val );
- if( p_val2 && p_val2->p_list )
+ switch( p_val->p_list->i_type & VLC_VAR_CLASS )
{
+ case VLC_VAR_STRING:
+ for( int i = 0; i < p_val->p_list->i_count; i++ )
+ free( p_val->p_list->p_values[i].psz_string );
+ break;
+ }
+
+ free( p_val->p_list->p_values );
+ free( p_val->p_list );
+
+ if( p_val2 != NULL )
+ {
+ assert( p_val2->p_list != NULL );
+ assert( p_val2->p_list->i_type == VLC_VAR_STRING );
+
for( int i = 0; i < p_val2->p_list->i_count; i++ )
free( p_val2->p_list->p_values[i].psz_string );
- if( p_val2->p_list->i_count )
- free( p_val2->p_list->p_values );
+ free( p_val2->p_list->p_values );
free( p_val2->p_list );
}
}