X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Fmisc%2Fvariables.c;h=72a59ca0946e5e3cebff3ab8c9e214986d5acd13;hb=1171979d73a6ddd4da292e772aa8d29d0e581996;hp=e87ba6ed3096f8b91f579c15077244e9d347092d;hpb=319e629d2c640cde2f7c42ab7429d5f324273a0b;p=vlc diff --git a/src/misc/variables.c b/src/misc/variables.c index e87ba6ed30..72a59ca094 100644 --- a/src/misc/variables.c +++ b/src/misc/variables.c @@ -2,7 +2,7 @@ * variables.c: routines for object variables handling ***************************************************************************** * Copyright (C) 2002 VideoLAN - * $Id: variables.c,v 1.11 2002/10/29 13:22:48 sam Exp $ + * $Id: variables.c,v 1.21 2003/03/11 23:56:54 gbazin Exp $ * * Authors: Samuel Hocevar * @@ -10,7 +10,7 @@ * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the @@ -51,23 +51,24 @@ static int CmpAddress( vlc_value_t v, vlc_value_t w ) { return v.p_address == w. /***************************************************************************** * Local duplication functions, and local deallocation functions *****************************************************************************/ -static void DupDummy( vlc_value_t *p_val ) { ; } +static void DupDummy( vlc_value_t *p_val ) { (void)p_val; /* unused */ } static void DupString( vlc_value_t *p_val ) { p_val->psz_string = strdup( p_val->psz_string ); } -static void FreeDummy( vlc_value_t *p_val ) { ; } +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 FreeMutex( vlc_value_t *p_val ) { vlc_mutex_destroy( (vlc_mutex_t*)p_val->p_address ); free( p_val->p_address ); } /***************************************************************************** * Local prototypes *****************************************************************************/ -static int GetUnused ( vlc_object_t *, const char * ); -static u32 HashString ( const char * ); -static int Insert ( variable_t *, int, const char * ); -static int InsertInner ( variable_t *, int, u32 ); -static int Lookup ( variable_t *, int, const char * ); -static int LookupInner ( variable_t *, int, u32 ); +static int GetUnused ( vlc_object_t *, const char * ); +static uint32_t HashString ( const char * ); +static int Insert ( variable_t *, int, const char * ); +static int InsertInner ( variable_t *, int, uint32_t ); +static int Lookup ( variable_t *, int, const char * ); +static int LookupInner ( variable_t *, int, uint32_t ); -static void CheckValue ( variable_t *, vlc_value_t * ); +static void CheckValue ( variable_t *, vlc_value_t * ); /***************************************************************************** * var_Create: initialize a vlc variable @@ -131,8 +132,8 @@ int __var_Create( vlc_object_t *p_this, const char *psz_name, int i_type ) p_var->i_usage = 1; p_var->i_default = -1; - p_var->i_choices = 0; - p_var->pp_choices = NULL; + p_var->choices.i_count = 0; + p_var->choices.p_values = NULL; p_var->b_incallback = VLC_FALSE; p_var->i_entries = 0; @@ -154,6 +155,8 @@ int __var_Create( vlc_object_t *p_this, const char *psz_name, int i_type ) case VLC_VAR_STRING: case VLC_VAR_MODULE: case VLC_VAR_FILE: + case VLC_VAR_DIRECTORY: + case VLC_VAR_VARIABLE: p_var->pf_cmp = CmpString; p_var->pf_dup = DupString; p_var->pf_free = FreeString; @@ -167,12 +170,12 @@ int __var_Create( vlc_object_t *p_this, const char *psz_name, int i_type ) /* FIXME: TODO */ break; case VLC_VAR_ADDRESS: - case VLC_VAR_COMMAND: p_var->pf_cmp = CmpAddress; p_var->val.p_address = NULL; break; case VLC_VAR_MUTEX: p_var->pf_cmp = CmpAddress; + p_var->pf_free = FreeMutex; p_var->val.p_address = malloc( sizeof(vlc_mutex_t) ); vlc_mutex_init( p_this, (vlc_mutex_t*)p_var->val.p_address ); break; @@ -218,23 +221,14 @@ int __var_Destroy( vlc_object_t *p_this, const char *psz_name ) /* Free value if needed */ p_var->pf_free( &p_var->val ); - switch( p_var->i_type & VLC_VAR_TYPE ) - { - /* XXX: find a way to put this in pf_free */ - case VLC_VAR_MUTEX: - vlc_mutex_destroy( (vlc_mutex_t*)p_var->val.p_address ); - free( p_var->val.p_address ); - break; - } - /* Free choice list if needed */ - if( p_var->pp_choices ) + if( p_var->choices.i_count ) { - for( i = 0 ; i < p_var->i_choices ; i++ ) + for( i = 0 ; i < p_var->choices.i_count ; i++ ) { - p_var->pf_free( &p_var->pp_choices[i] ); + p_var->pf_free( &p_var->choices.p_values[i] ); } - free( p_var->pp_choices ); + free( p_var->choices.p_values ); } /* Free callbacks if needed */ @@ -265,13 +259,14 @@ int __var_Destroy( vlc_object_t *p_this, const char *psz_name ) /***************************************************************************** * var_Change: perform an action on a variable ***************************************************************************** - * + * *****************************************************************************/ int __var_Change( vlc_object_t *p_this, const char *psz_name, int i_action, vlc_value_t *p_val ) { int i_var, i; variable_t *p_var; + vlc_value_t oldval; vlc_mutex_lock( &p_this->var_lock ); @@ -317,12 +312,11 @@ int __var_Change( vlc_object_t *p_this, const char *psz_name, p_var->pf_dup( &p_var->step ); CheckValue( p_var, &p_var->val ); break; - case VLC_VAR_ADDCHOICE: /* FIXME: the list is sorted, dude. Use something cleverer. */ - for( i = p_var->i_choices ; i-- ; ) + for( i = p_var->choices.i_count ; i-- ; ) { - if( p_var->pf_cmp( p_var->pp_choices[i], *p_val ) < 0 ) + if( p_var->pf_cmp( p_var->choices.p_values[i], *p_val ) < 0 ) { break; } @@ -336,22 +330,23 @@ int __var_Change( vlc_object_t *p_this, const char *psz_name, p_var->i_default++; } - INSERT_ELEM( p_var->pp_choices, p_var->i_choices, i, *p_val ); - p_var->pf_dup( &p_var->pp_choices[i] ); + INSERT_ELEM( p_var->choices.p_values, p_var->choices.i_count, + i, *p_val ); + p_var->pf_dup( &p_var->choices.p_values[i] ); CheckValue( p_var, &p_var->val ); break; case VLC_VAR_DELCHOICE: /* FIXME: the list is sorted, dude. Use something cleverer. */ - for( i = 0 ; i < p_var->i_choices ; i++ ) + for( i = 0 ; i < p_var->choices.i_count ; i++ ) { - if( p_var->pf_cmp( p_var->pp_choices[i], *p_val ) == 0 ) + if( p_var->pf_cmp( p_var->choices.p_values[i], *p_val ) == 0 ) { break; } } - if( i == p_var->i_choices ) + if( i == p_var->choices.i_count ) { /* Not found */ vlc_mutex_unlock( &p_this->var_lock ); @@ -367,22 +362,34 @@ int __var_Change( vlc_object_t *p_this, const char *psz_name, p_var->i_default = -1; } - p_var->pf_free( &p_var->pp_choices[i] ); - REMOVE_ELEM( p_var->pp_choices, p_var->i_choices, i ); + p_var->pf_free( &p_var->choices.p_values[i] ); + REMOVE_ELEM( p_var->choices.p_values, p_var->choices.i_count, i ); CheckValue( p_var, &p_var->val ); break; + case VLC_VAR_CLEARCHOICES: + for( i = 0 ; i < p_var->choices.i_count ; i++ ) + { + p_var->pf_free( &p_var->choices.p_values[i] ); + } + if( p_var->choices.i_count ) + free( p_var->choices.p_values ); + + p_var->choices.i_count = 0; + p_var->choices.p_values = NULL; + p_var->i_default = -1; + break; case VLC_VAR_SETDEFAULT: /* FIXME: the list is sorted, dude. Use something cleverer. */ - for( i = 0 ; i < p_var->i_choices ; i++ ) + for( i = 0 ; i < p_var->choices.i_count ; i++ ) { - if( p_var->pf_cmp( p_var->pp_choices[i], *p_val ) == 0 ) + if( p_var->pf_cmp( p_var->choices.p_values[i], *p_val ) == 0 ) { break; } } - if( i == p_var->i_choices ) + if( i == p_var->choices.i_count ) { /* Not found */ break; @@ -391,23 +398,38 @@ int __var_Change( vlc_object_t *p_this, const char *psz_name, p_var->i_default = i; CheckValue( p_var, &p_var->val ); break; - + case VLC_VAR_SETVALUE: + /* Duplicate data if needed */ + p_var->pf_dup( p_val ); + /* Backup needed stuff */ + oldval = p_var->val; + /* Check boundaries and list */ + CheckValue( p_var, p_val ); + /* Set the variable */ + p_var->val = *p_val; + /* Free data if needed */ + p_var->pf_free( &oldval ); + break; case VLC_VAR_GETLIST: - p_val->p_address = malloc( (1 + p_var->i_choices) - * sizeof(vlc_value_t) ); - ((vlc_value_t*)p_val->p_address)[0].i_int = p_var->i_choices; - for( i = 0 ; i < p_var->i_choices ; i++ ) + p_val->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) ); + p_val->p_list->i_count = p_var->choices.i_count; + for( i = 0 ; i < p_var->choices.i_count ; i++ ) { - ((vlc_value_t*)p_val->p_address)[i+1] = p_var->pp_choices[i]; - p_var->pf_dup( &((vlc_value_t*)p_val->p_address)[i+1] ); + p_val->p_list->p_values[i] = p_var->choices.p_values[i]; + p_var->pf_dup( &p_val->p_list->p_values[i] ); } break; case VLC_VAR_FREELIST: - for( i = ((vlc_value_t*)p_val->p_address)[0].i_int ; i-- ; ) + for( i = p_val->p_list->i_count ; i-- ; ) { - p_var->pf_free( &((vlc_value_t*)p_val->p_address)[i+1] ); + p_var->pf_free( &p_val->p_list->p_values[i] ); } - free( p_val->p_address ); + if( p_val->p_list->i_count ) + free( p_val->p_list->p_values ); + free( p_val->p_list ); break; default: @@ -420,9 +442,10 @@ int __var_Change( vlc_object_t *p_this, const char *psz_name, } /***************************************************************************** - * var_Type: request a variable's type, 0 if not found + * var_Type: request a variable's type ***************************************************************************** - * + * This function returns the variable type if it exists, or 0 if the + * variable could not be found. *****************************************************************************/ int __var_Type( vlc_object_t *p_this, const char *psz_name ) { @@ -476,6 +499,9 @@ int __var_Set( vlc_object_t *p_this, const char *psz_name, vlc_value_t val ) /* Check boundaries and list */ CheckValue( p_var, &val ); + /* Set the variable */ + p_var->val = val; + /* Deal with callbacks. Tell we're in a callback, release the lock, * call stored functions, retake the lock. */ if( p_var->i_entries ) @@ -499,7 +525,7 @@ int __var_Set( vlc_object_t *p_this, const char *psz_name, vlc_value_t val ) i_var = Lookup( p_this->p_vars, p_this->i_vars, psz_name ); if( i_var < 0 ) { - msg_Err( p_this, "variable %s has disappeared" ); + msg_Err( p_this, "variable %s has disappeared", psz_name ); vlc_mutex_unlock( &p_this->var_lock ); return VLC_ENOVAR; } @@ -508,9 +534,6 @@ int __var_Set( vlc_object_t *p_this, const char *psz_name, vlc_value_t val ) p_var->b_incallback = VLC_FALSE; } - /* Set the variable */ - p_var->val = val; - /* Free data if needed */ p_var->pf_free( &oldval ); @@ -541,30 +564,6 @@ int __var_Get( vlc_object_t *p_this, const char *psz_name, vlc_value_t *p_val ) p_var = &p_this->p_vars[i_var]; - /* Some variables trigger special behaviour. */ - switch( p_var->i_type & VLC_VAR_TYPE ) - { - case VLC_VAR_COMMAND: - if( p_var->val.p_address ) - { - /* We need to save data before releasing the lock */ - int i_ret; - int (*pf_command) (vlc_object_t *, char *, char *) = - p_var->val.p_address; - char *psz_cmd = strdup( p_var->psz_name ); - char *psz_arg = strdup( p_val->psz_string ); - - vlc_mutex_unlock( &p_this->var_lock ); - - i_ret = pf_command( p_this, psz_cmd, psz_arg ); - free( psz_cmd ); - free( psz_arg ); - - return i_ret; - } - break; - } - /* Really get the variable */ *p_val = p_var->val; @@ -592,7 +591,7 @@ int __var_AddCallback( vlc_object_t *p_this, const char *psz_name, entry.pf_callback = pf_callback; entry.p_data = p_data; - + vlc_mutex_lock( &p_this->var_lock ); i_var = GetUnused( p_this, psz_name ); @@ -640,7 +639,7 @@ int __var_DelCallback( vlc_object_t *p_this, const char *psz_name, for( i_entry = p_var->i_entries ; i_entry-- ; ) { if( p_var->p_entries[i_entry].pf_callback == pf_callback - || p_var->p_entries[i_entry].p_data == p_data ) + && p_var->p_entries[i_entry].p_data == p_data ) { break; } @@ -703,9 +702,9 @@ static int GetUnused( vlc_object_t *p_this, const char *psz_name ) * fast and not suck too much. This one is pretty fast and did 0 collisions * in wenglish's dictionary. *****************************************************************************/ -static u32 HashString( const char *psz_string ) +static uint32_t HashString( const char *psz_string ) { - u32 i_hash = 0; + uint32_t i_hash = 0; while( *psz_string ) { @@ -735,7 +734,7 @@ static int Insert( variable_t *p_vars, int i_count, const char *psz_name ) return InsertInner( p_vars, i_count, HashString( psz_name ) ); } -static int InsertInner( variable_t *p_vars, int i_count, u32 i_hash ) +static int InsertInner( variable_t *p_vars, int i_count, uint32_t i_hash ) { int i_middle; @@ -777,7 +776,7 @@ static int InsertInner( variable_t *p_vars, int i_count, u32 i_hash ) *****************************************************************************/ static int Lookup( variable_t *p_vars, int i_count, const char *psz_name ) { - u32 i_hash; + uint32_t i_hash; int i, i_pos; if( i_count == 0 ) @@ -824,7 +823,7 @@ static int Lookup( variable_t *p_vars, int i_count, const char *psz_name ) return -1; } -static int LookupInner( variable_t *p_vars, int i_count, u32 i_hash ) +static int LookupInner( variable_t *p_vars, int i_count, uint32_t i_hash ) { int i_middle; @@ -867,14 +866,14 @@ static int LookupInner( variable_t *p_vars, int i_count, u32 i_hash ) static void CheckValue ( variable_t *p_var, vlc_value_t *p_val ) { /* Check that our variable is in the list */ - if( p_var->i_type & VLC_VAR_ISLIST && p_var->i_choices ) + if( p_var->i_type & VLC_VAR_HASCHOICE && p_var->choices.i_count ) { int i; /* FIXME: the list is sorted, dude. Use something cleverer. */ - for( i = p_var->i_choices ; i-- ; ) + for( i = p_var->choices.i_count ; i-- ; ) { - if( p_var->pf_cmp( *p_val, p_var->pp_choices[i] ) == 0 ) + if( p_var->pf_cmp( *p_val, p_var->choices.p_values[i] ) == 0 ) { break; } @@ -885,8 +884,8 @@ static void CheckValue ( variable_t *p_var, vlc_value_t *p_val ) { /* Free the old variable, get the new one, dup it */ p_var->pf_free( p_val ); - *p_val = p_var->pp_choices[p_var->i_default >= 0 - ? p_var->i_default : 0 ]; + *p_val = p_var->choices.p_values[p_var->i_default >= 0 + ? p_var->i_default : 0 ]; p_var->pf_dup( p_val ); } } @@ -938,4 +937,3 @@ static void CheckValue ( variable_t *p_var, vlc_value_t *p_val ) break; } } -