* Make ParseOption (from input) a global service (var_OptionParse)
authorClément Stenac <zorglub@videolan.org>
Sun, 22 Jan 2006 17:12:24 +0000 (17:12 +0000)
committerClément Stenac <zorglub@videolan.org>
Sun, 22 Jan 2006 17:12:24 +0000 (17:12 +0000)
* Add i_options/pp_options to intf_Create

* add global options to enable file-logging and syslog (Refs:#508)

include/variables.h
include/vlc_interface.h
include/vlc_symbols.h
modules/codec/cmml/cmml.c
modules/control/rc.c
modules/misc/logger.c
src/input/input.c
src/interface/interface.c
src/libvlc.c
src/libvlc.h
src/misc/variables.c

index 21a50eb..a906b0e 100644 (file)
@@ -163,6 +163,9 @@ VLC_EXPORT( int, __var_Type, ( vlc_object_t *, const char * ) );
 VLC_EXPORT( int, __var_Set, ( vlc_object_t *, const char *, vlc_value_t ) );
 VLC_EXPORT( int, __var_Get, ( vlc_object_t *, const char *, vlc_value_t * ) );
 
+#define var_OptionParse(a,b) __var_OptionParse( VLC_OBJECT( a ) , b )
+VLC_EXPORT( void, __var_OptionParse, ( vlc_object_t *, const char * ) );
+
 /**
  * __var_Create() with automatic casting.
  */
index e359257..0b8747a 100644 (file)
@@ -113,8 +113,8 @@ struct intf_dialog_args_t
 /*****************************************************************************
  * Prototypes
  *****************************************************************************/
-#define intf_Create(a,b) __intf_Create(VLC_OBJECT(a),b)
-VLC_EXPORT( intf_thread_t *, __intf_Create,     ( vlc_object_t *, const char * ) );
+#define intf_Create(a,b,c,d) __intf_Create(VLC_OBJECT(a),b,c,d)
+VLC_EXPORT( intf_thread_t *, __intf_Create,     ( vlc_object_t *, const char *, int, char ** ) );
 VLC_EXPORT( int,               intf_RunThread,  ( intf_thread_t * ) );
 VLC_EXPORT( void,              intf_StopThread, ( intf_thread_t * ) );
 VLC_EXPORT( void,              intf_Destroy,    ( intf_thread_t * ) );
index da9d406..b86c51c 100644 (file)
@@ -55,6 +55,7 @@ int __vout_AllocatePicture (vlc_object_t *p_this, picture_t *p_pic, uint32_t i_c
 playlist_item_t * playlist_NodeCreate (playlist_t *,int,char *, playlist_item_t * p_parent);
 void * vlc_readdir (void *);
 int sout_AnnounceRegister (sout_instance_t *,session_descriptor_t*, announce_method_t*);
+void __var_OptionParse (vlc_object_t *, const char *);
 int osd_ShowTextRelative (spu_t *, int, char *, text_style_t *, int, int, int, mtime_t);
 void * __vlc_object_get (vlc_object_t *, int);
 void vout_SynchroTrash (vout_synchro_t *);
@@ -279,7 +280,7 @@ int __vlc_thread_set_priority (vlc_object_t *, char *, int, int);
 int ACL_LoadFile (vlc_acl_t *p_acl, const char *path);
 void input_StopThread (input_thread_t *);
 int __input_Read (vlc_object_t *, input_item_t *, vlc_bool_t);
-intf_thread_t * __intf_Create (vlc_object_t *, const char *);
+intf_thread_t * __intf_Create (vlc_object_t *, const char *, int, char **);
 void aout_ChannelReorder (uint8_t *, int, int, const int *, int);
 int __var_DelCallback (vlc_object_t *, const char *, vlc_callback_t, void *);
 void __vlc_object_detach (vlc_object_t *);
@@ -675,7 +676,7 @@ struct module_symbols_t
     decoder_t * (*input_DecoderNew_inner) (input_thread_t *, es_format_t *, vlc_bool_t b_force_decoder);
     void (*input_DecoderDelete_inner) (decoder_t *);
     void (*input_DecoderDecode_inner) (decoder_t *, block_t *);
-    intf_thread_t * (*__intf_Create_inner) (vlc_object_t *, const char *);
+    intf_thread_t * (*__intf_Create_inner) (vlc_object_t *, const char *, int, char **);
     int (*intf_RunThread_inner) (intf_thread_t *);
     void (*intf_StopThread_inner) (intf_thread_t *);
     void (*intf_Destroy_inner) (intf_thread_t *);
@@ -890,6 +891,7 @@ struct module_symbols_t
     input_thread_t * (*__input_CreateThread2_inner) (vlc_object_t *, input_item_t *, char *);
     void (*stats_HandlerDestroy_inner) (stats_handler_t*);
     vlc_t * (*vlc_current_object_inner) (int);
+    void (*__var_OptionParse_inner) (vlc_object_t *, const char *);
 };
 #  if defined (__PLUGIN__)
 #  define aout_FiltersCreatePipeline (p_symbols)->aout_FiltersCreatePipeline_inner
@@ -1320,6 +1322,7 @@ struct module_symbols_t
 #  define __input_CreateThread2 (p_symbols)->__input_CreateThread2_inner
 #  define stats_HandlerDestroy (p_symbols)->stats_HandlerDestroy_inner
 #  define vlc_current_object (p_symbols)->vlc_current_object_inner
+#  define __var_OptionParse (p_symbols)->__var_OptionParse_inner
 #  elif defined (HAVE_DYNAMIC_PLUGINS) && !defined (__BUILTIN__)
 /******************************************************************
  * STORE_SYMBOLS: store VLC APIs into p_symbols for plugin access.
@@ -1753,6 +1756,7 @@ struct module_symbols_t
     ((p_symbols)->__input_CreateThread2_inner) = __input_CreateThread2; \
     ((p_symbols)->stats_HandlerDestroy_inner) = stats_HandlerDestroy; \
     ((p_symbols)->vlc_current_object_inner) = vlc_current_object; \
+    ((p_symbols)->__var_OptionParse_inner) = __var_OptionParse; \
     (p_symbols)->net_ConvertIPv4_deprecated = NULL; \
     (p_symbols)->__stats_CounterGet_deprecated = NULL; \
 
index f58cf64..f0f12e2 100644 (file)
@@ -128,7 +128,7 @@ static int OpenDecoder( vlc_object_t *p_this )
     vlc_object_release( p_input );
 
     /* initialise the CMML responder interface */
-    p_sys->p_intf = intf_Create( p_dec, "cmml" );
+    p_sys->p_intf = intf_Create( p_dec, "cmml", 0, NULL );
     p_sys->p_intf->b_block = VLC_FALSE;
     intf_RunThread( p_sys->p_intf );
 
index 0e55f9f..2d4d4bf 100644 (file)
@@ -1670,7 +1670,7 @@ static int Quit( vlc_object_t *p_this, char const *psz_cmd,
     {
         playlist_Stop( p_playlist );
         vlc_object_release( p_playlist );
-    }    
+    }
     p_this->p_vlc->b_die = VLC_TRUE;
     return VLC_SUCCESS;
 }
@@ -1680,7 +1680,7 @@ static int Intf( vlc_object_t *p_this, char const *psz_cmd,
 {
     intf_thread_t *p_newintf = NULL;
 
-    p_newintf = intf_Create( p_this->p_vlc, newval.psz_string );
+    p_newintf = intf_Create( p_this->p_vlc, newval.psz_string, 0, NULL );
     if( p_newintf )
     {
         p_newintf->b_block = VLC_FALSE;
index 5bc6364..585b78d 100644 (file)
@@ -118,12 +118,11 @@ static char *mode_list_text[] = { N_("Text"), "HTML"
 #endif
 
 vlc_module_begin();
-    set_category( CAT_INTERFACE );
-    set_subcategory( SUBCAT_INTERFACE_CONTROL );
     set_shortname( N_( "Logging" ) );
     set_description( _("File logging") );
 
-    add_file( "logfile", NULL, NULL, N_("Log filename"), N_("Specify the log filename."), VLC_FALSE );
+    add_file( "logfile", NULL, NULL,
+             N_("Log filename"), N_("Specify the log filename."), VLC_FALSE );
     add_string( "logmode", "text", NULL, LOGMODE_TEXT, LOGMODE_LONGTEXT,
                 VLC_FALSE );
         change_string_list( mode_list, mode_list_text, 0 );
@@ -151,7 +150,7 @@ static int Open( vlc_object_t *p_this )
         return -1;
     }
 
-    psz_mode = config_GetPsz( p_intf, "logmode" );
+    psz_mode = var_CreateGetString( p_intf, "logmode" );
     if( psz_mode )
     {
         if( !strcmp( psz_mode, "text" ) )
index d7f47c8..2fb71a3 100644 (file)
@@ -64,8 +64,6 @@ static int  UpdateMeta( input_thread_t *, vlc_bool_t );
 
 static void UpdateItemLength( input_thread_t *, int64_t i_length, vlc_bool_t );
 
-static void ParseOption( input_thread_t *p_input, const char *psz_option );
-
 static void DecodeUrl( char * );
 static void MRLSections( input_thread_t *, char *, int *, int *, int *, int *);
 
@@ -166,7 +164,7 @@ static input_thread_t *Create( vlc_object_t *p_parent, input_item_t *p_item,
     vlc_mutex_lock( &p_item->lock );
     for( i = 0; i < p_item->i_options; i++ )
     {
-        ParseOption( p_input, p_item->ppsz_options[i] );
+        var_OptionParse( p_input, p_item->ppsz_options[i] );
     }
     vlc_mutex_unlock( &p_item->lock );
 
@@ -2411,138 +2409,6 @@ static void DecodeUrl( char *psz )
     if( dup ) free( dup );
 }
 
-/*****************************************************************************
- * ParseOption: parses the options for the input
- *****************************************************************************
- * This function parses the input (config) options and creates their associated
- * object variables.
- * Options are of the form "[no[-]]foo[=bar]" where foo is the option name and
- * bar is the value of the option.
- *****************************************************************************/
-static void ParseOption( input_thread_t *p_input, const char *psz_option )
-{
-    char *psz_name = (char *)psz_option;
-    char *psz_value = strchr( psz_option, '=' );
-    int  i_name_len, i_type;
-    vlc_bool_t b_isno = VLC_FALSE;
-    vlc_value_t val;
-
-    if( psz_value ) i_name_len = psz_value - psz_option;
-    else i_name_len = strlen( psz_option );
-
-    /* It's too much of an hassle to remove the ':' when we parse
-     * the cmd line :) */
-    if( i_name_len && *psz_name == ':' )
-    {
-        psz_name++;
-        i_name_len--;
-    }
-
-    if( i_name_len == 0 ) return;
-
-    psz_name = strndup( psz_name, i_name_len );
-    if( psz_value ) psz_value++;
-
-    /* FIXME: :programs should be handled generically */
-    if( !strcmp( psz_name, "programs" ) )
-        i_type = VLC_VAR_LIST;
-    else
-        i_type = config_GetType( p_input, psz_name );
-
-    if( !i_type && !psz_value )
-    {
-        /* check for "no-foo" or "nofoo" */
-        if( !strncmp( psz_name, "no-", 3 ) )
-        {
-            memmove( psz_name, psz_name + 3, strlen(psz_name) + 1 - 3 );
-        }
-        else if( !strncmp( psz_name, "no", 2 ) )
-        {
-            memmove( psz_name, psz_name + 2, strlen(psz_name) + 1 - 2 );
-        }
-        else goto cleanup;           /* Option doesn't exist */
-
-        b_isno = VLC_TRUE;
-        i_type = config_GetType( p_input, psz_name );
-
-        if( !i_type ) goto cleanup;  /* Option doesn't exist */
-    }
-    else if( !i_type ) goto cleanup; /* Option doesn't exist */
-
-    if( ( i_type != VLC_VAR_BOOL ) &&
-        ( !psz_value || !*psz_value ) ) goto cleanup; /* Invalid value */
-
-    /* Create the variable in the input object.
-     * Children of the input object will be able to retreive this value
-     * thanks to the inheritance property of the object variables. */
-    var_Create( p_input, psz_name, i_type );
-
-    switch( i_type )
-    {
-    case VLC_VAR_BOOL:
-        val.b_bool = !b_isno;
-        break;
-
-    case VLC_VAR_INTEGER:
-        val.i_int = strtol( psz_value, NULL, 0 );
-        break;
-
-    case VLC_VAR_FLOAT:
-        val.f_float = atof( psz_value );
-        break;
-
-    case VLC_VAR_STRING:
-    case VLC_VAR_MODULE:
-    case VLC_VAR_FILE:
-    case VLC_VAR_DIRECTORY:
-        val.psz_string = psz_value;
-        break;
-
-    case VLC_VAR_LIST:
-    {
-        char *psz_orig, *psz_var;
-        vlc_list_t *p_list = malloc(sizeof(vlc_list_t));
-        val.p_list = p_list;
-        p_list->i_count = 0;
-
-        psz_var = psz_orig = strdup(psz_value);
-        while( psz_var && *psz_var )
-        {
-            char *psz_item = psz_var;
-            vlc_value_t val2;
-            while( *psz_var && *psz_var != ',' ) psz_var++;
-            if( *psz_var == ',' )
-            {
-                *psz_var = '\0';
-                psz_var++;
-            }
-            val2.i_int = strtol( psz_item, NULL, 0 );
-            INSERT_ELEM( p_list->p_values, p_list->i_count,
-                         p_list->i_count, val2 );
-            /* p_list->i_count is incremented twice by INSERT_ELEM */
-            p_list->i_count--;
-            INSERT_ELEM( p_list->pi_types, p_list->i_count,
-                         p_list->i_count, VLC_VAR_INTEGER );
-        }
-        if( psz_orig ) free( psz_orig );
-        break;
-    }
-
-    default:
-        goto cleanup;
-        break;
-    }
-
-    var_Set( p_input, psz_name, val );
-
-    msg_Dbg( p_input, "set input option: %s to %s", psz_name,
-             psz_value ? psz_value : ( val.b_bool ? "true" : "false") );
-
-  cleanup:
-    if( psz_name ) free( psz_name );
-    return;
-}
-
 /*****************************************************************************
  * MRLSplit: parse the access, demux and url part of the
  *           Media Resource Locator.
index 6439ceb..9350bc8 100644 (file)
@@ -82,14 +82,19 @@ static int AddIntfCallback( vlc_object_t *, char const *,
  *****************************************************************************/
 /**
  * Create the interface, and prepare it for main loop.
+ * You can give some additional options to be used for interface initialization
  *
  * \param p_this the calling vlc_object_t
  * \param psz_module a prefered interface module
+ * \param i_options number additional options
+ * \param ppsz_options additional option strings
  * \return a pointer to the created interface thread, NULL on error
  */
-intf_thread_t* __intf_Create( vlc_object_t *p_this, const char *psz_module )
+intf_thread_t* __intf_Create( vlc_object_t *p_this, const char *psz_module,
+                              int i_options, char **ppsz_options  )
 {
     intf_thread_t * p_intf;
+    int i;
 
     /* Allocate structure */
     p_intf = vlc_object_create( p_this, VLC_OBJECT_INTF );
@@ -104,6 +109,11 @@ intf_thread_t* __intf_Create( vlc_object_t *p_this, const char *psz_module )
     p_intf->b_play = VLC_FALSE;
     p_intf->b_interaction = VLC_FALSE;
 
+    for( i = 0 ; i< i_options; i++ )
+    {
+        var_OptionParse( p_intf, ppsz_options[i] );
+    }
+
     /* Choose the best module */
     p_intf->p_module = module_Need( p_intf, "interface", psz_module, 0 );
 
@@ -121,8 +131,6 @@ intf_thread_t* __intf_Create( vlc_object_t *p_this, const char *psz_module )
     /* Initialize mutexes */
     vlc_mutex_init( p_intf, &p_intf->change_lock );
 
-    msg_Dbg( p_intf, "interface initialized" );
-
     /* Attach interface to its parent object */
     vlc_object_attach( p_intf, p_this );
 
@@ -428,7 +436,7 @@ static int AddIntfCallback( vlc_object_t *p_this, char const *psz_cmd,
 
     /* Try to create the interface */
     sprintf( psz_intf, "%s,none", newval.psz_string );
-    p_intf = intf_Create( p_this->p_vlc, psz_intf );
+    p_intf = intf_Create( p_this->p_vlc, psz_intf, 0, NULL );
     free( psz_intf );
     if( p_intf == NULL )
     {
index 5916774..8a7d294 100644 (file)
@@ -92,6 +92,10 @@ static vlc_t *    p_static_vlc;
 /*****************************************************************************
  * Local prototypes
  *****************************************************************************/
+static int AddIntfInternal( int i_object, char const *psz_module,
+                             vlc_bool_t b_block, vlc_bool_t b_play,
+                             int i_options, char **ppsz_options );
+
 static void LocaleInit( void );
 static void LocaleDeinit( void );
 static void SetLanguage   ( char const * );
@@ -772,6 +776,16 @@ int VLC_Init( int i_object, int i_argc, char *ppsz_argv[] )
     }
 #endif
 
+    if( config_GetInt( p_vlc, "file-logging" ) == 1 )
+    {
+        VLC_AddIntf( 0, "logger", VLC_FALSE, VLC_FALSE );
+    }
+    if( config_GetInt( p_vlc, "syslog" ) == 1 )
+    {
+        char *psz_logmode = "logmode=syslog";
+        AddIntfInternal( 0, "logger", VLC_FALSE, VLC_FALSE, 1, &psz_logmode );
+    }
+
     /*
      * FIXME: kludge to use a p_vlc-local variable for the Mozilla plugin
      */
@@ -824,55 +838,10 @@ int VLC_Init( int i_object, int i_argc, char *ppsz_argv[] )
 int VLC_AddIntf( int i_object, char const *psz_module,
                  vlc_bool_t b_block, vlc_bool_t b_play )
 {
-    int i_err;
-    intf_thread_t *p_intf;
-    vlc_t *p_vlc = vlc_current_object( i_object );
-
-    if( !p_vlc )
-    {
-        return VLC_ENOOBJ;
-    }
-
-#ifndef WIN32
-    if( p_vlc->p_libvlc->b_daemon && b_block && !psz_module )
-    {
-        /* Daemon mode hack.
-         * We prefer the dummy interface if none is specified. */
-        char *psz_interface = config_GetPsz( p_vlc, "intf" );
-        if( !psz_interface || !*psz_interface ) psz_module = "dummy";
-        if( psz_interface ) free( psz_interface );
-    }
-#endif
-
-    /* Try to create the interface */
-    p_intf = intf_Create( p_vlc, psz_module ? psz_module : "$intf" );
-
-    if( p_intf == NULL )
-    {
-        msg_Err( p_vlc, "interface \"%s\" initialization failed", psz_module );
-        if( i_object ) vlc_object_release( p_vlc );
-        return VLC_EGENERIC;
-    }
-
-    /* Interface doesn't handle play on start so do it ourselves */
-    if( !p_intf->b_play && b_play ) VLC_Play( i_object );
-
-    /* Try to run the interface */
-    p_intf->b_play = b_play;
-    p_intf->b_block = b_block;
-    i_err = intf_RunThread( p_intf );
-    if( i_err )
-    {
-        vlc_object_detach( p_intf );
-        intf_Destroy( p_intf );
-        if( i_object ) vlc_object_release( p_vlc );
-        return i_err;
-    }
-
-    if( i_object ) vlc_object_release( p_vlc );
-    return VLC_SUCCESS;
+    return AddIntfInternal( i_object, psz_module, b_block, b_play, 0, NULL );
 }
 
+
 /*****************************************************************************
  * VLC_Die: ask vlc to die.
  *****************************************************************************
@@ -1913,6 +1882,66 @@ int VLC_FullScreen( int i_object )
 
 /* following functions are local */
 
+
+static int  AddIntfInternal( int i_object, char const *psz_module,
+                             vlc_bool_t b_block, vlc_bool_t b_play,
+                             int i_options, char **ppsz_options )
+{
+    int i_err,i;
+    intf_thread_t *p_intf;
+    vlc_t *p_vlc = vlc_current_object( i_object );
+
+    if( !p_vlc )
+    {
+        return VLC_ENOOBJ;
+    }
+
+#ifndef WIN32
+    if( p_vlc->p_libvlc->b_daemon && b_block && !psz_module )
+    {
+        /* Daemon mode hack.
+         * We prefer the dummy interface if none is specified. */
+        char *psz_interface = config_GetPsz( p_vlc, "intf" );
+        if( !psz_interface || !*psz_interface ) psz_module = "dummy";
+        if( psz_interface ) free( psz_interface );
+    }
+#endif
+
+    /* Try to create the interface */
+    p_intf = intf_Create( p_vlc, psz_module ? psz_module : "$intf",
+                          i_options, ppsz_options );
+
+    if( p_intf == NULL )
+    {
+        msg_Err( p_vlc, "interface \"%s\" initialization failed", psz_module );
+        if( i_object ) vlc_object_release( p_vlc );
+        return VLC_EGENERIC;
+    }
+
+    /* Interface doesn't handle play on start so do it ourselves */
+    if( !p_intf->b_play && b_play ) VLC_Play( i_object );
+
+    /* Try to run the interface */
+    p_intf->b_play = b_play;
+    p_intf->b_block = b_block;
+    i_err = intf_RunThread( p_intf );
+    if( i_err )
+    {
+        vlc_object_detach( p_intf );
+        intf_Destroy( p_intf );
+        if( i_object ) vlc_object_release( p_vlc );
+        return i_err;
+    }
+
+    for( i = 0  ; i< i_options ; i++ )
+    {
+        
+    }
+
+    if( i_object ) vlc_object_release( p_vlc );
+    return VLC_SUCCESS;
+};
+
 static void LocaleInit( void )
 {
     char *psz_charset;
index 9d5336d..b580ee3 100644 (file)
@@ -264,6 +264,13 @@ static char *ppsz_align_descriptions[] =
 #define SS_TEXT N_("Disable screensaver")
 #define SS_LONGTEXT N_("Disable the screensaver during video playback." )
 
+#define FILE_LOG_TEXT N_( "Log to file" )
+#define FILE_LOG_LONGTEXT N_( "Log all VLC messages to a text file. Use the "\
+    "logfile option to set the file name." )
+
+#define SYSLOG_TEXT N_( "Log to syslog" )
+#define SYSLOG_LONGTEXT N_( "Log all VLC messages to syslog." )
+
 #define VIDEO_DECO_TEXT N_("Window decorations")
 #define VIDEO_DECO_LONGTEXT N_( \
     "If this option is disabled, VLC will avoid creating window caption, " \
@@ -1076,6 +1083,13 @@ vlc_module_begin();
     add_bool( "disable-screensaver", VLC_TRUE, NULL, SS_TEXT, SS_LONGTEXT,
               VLC_TRUE );
 
+    add_bool( "file-logging", VLC_FALSE, NULL, FILE_LOG_TEXT, FILE_LOG_LONGTEXT,
+              VLC_TRUE );
+#if HAVE_SYSLOG_H
+    add_bool ( "syslog", VLC_FALSE, NULL, SYSLOG_TEXT, SYSLOG_LONGTEXT,
+               VLC_TRUE );
+#endif
+
     set_section( N_("Snapshot") , NULL );
     add_directory( "snapshot-path", NULL, NULL, SNAP_PATH_TEXT,
                    SNAP_PATH_LONGTEXT, VLC_FALSE );
index fab11ec..6b54932 100644 (file)
@@ -917,6 +917,137 @@ int __var_DelCallback( vlc_object_t *p_this, const char *psz_name,
     return VLC_SUCCESS;
 }
 
+/** Parse a stringified option
+ * This function parse a string option and create the associated object
+ * variable
+ * The option must be of the form "[no[-]]foo[=bar]" where foo is the
+ * option name and bar is the value of the option.
+ * \param p_obj the object in which the variable must be created
+ * \param psz_option the option to parse
+ * \return nothing
+ */
+void __var_OptionParse( vlc_object_t *p_obj,const char *psz_option )
+{
+    char *psz_name = (char *)psz_option;
+    char *psz_value = strchr( psz_option, '=' );
+    int  i_name_len, i_type;
+    vlc_bool_t b_isno = VLC_FALSE;
+    vlc_value_t val;
+
+    if( psz_value ) i_name_len = psz_value - psz_option;
+    else i_name_len = strlen( psz_option );
+
+    /* It's too much of an hassle to remove the ':' when we parse
+     * the cmd line :) */
+    if( i_name_len && *psz_name == ':' )
+    {
+        psz_name++;
+        i_name_len--;
+    }
+
+    if( i_name_len == 0 ) return;
+
+    psz_name = strndup( psz_name, i_name_len );
+    if( psz_value ) psz_value++;
+
+    /* FIXME: :programs should be handled generically */
+    if( !strcmp( psz_name, "programs" ) )
+        i_type = VLC_VAR_LIST;
+    else
+        i_type = config_GetType( p_obj, psz_name );
+
+    if( !i_type && !psz_value )
+    {
+        /* check for "no-foo" or "nofoo" */
+        if( !strncmp( psz_name, "no-", 3 ) )
+        {
+            memmove( psz_name, psz_name + 3, strlen(psz_name) + 1 - 3 );
+        }
+        else if( !strncmp( psz_name, "no", 2 ) )
+        {
+            memmove( psz_name, psz_name + 2, strlen(psz_name) + 1 - 2 );
+        }
+        else goto cleanup;           /* Option doesn't exist */
+
+        b_isno = VLC_TRUE;
+        i_type = config_GetType( p_obj, psz_name );
+
+        if( !i_type ) goto cleanup;  /* Option doesn't exist */
+    }
+    else if( !i_type ) goto cleanup; /* Option doesn't exist */
+
+    if( ( i_type != VLC_VAR_BOOL ) &&
+        ( !psz_value || !*psz_value ) ) goto cleanup; /* Invalid value */
+
+    /* Create the variable in the input object.
+     * Children of the input object will be able to retreive this value
+     * thanks to the inheritance property of the object variables. */
+    var_Create( p_obj, psz_name, i_type );
+
+    switch( i_type )
+    {
+    case VLC_VAR_BOOL:
+        val.b_bool = !b_isno;
+        break;
+
+    case VLC_VAR_INTEGER:
+        val.i_int = strtol( psz_value, NULL, 0 );
+        break;
+
+    case VLC_VAR_FLOAT:
+        val.f_float = atof( psz_value );
+        break;
+
+    case VLC_VAR_STRING:
+    case VLC_VAR_MODULE:
+    case VLC_VAR_FILE:
+    case VLC_VAR_DIRECTORY:
+        val.psz_string = psz_value;
+        break;
+
+    case VLC_VAR_LIST:
+    {
+        char *psz_orig, *psz_var;
+        vlc_list_t *p_list = malloc(sizeof(vlc_list_t));
+        val.p_list = p_list;
+        p_list->i_count = 0;
+
+        psz_var = psz_orig = strdup(psz_value);
+        while( psz_var && *psz_var )
+        {
+            char *psz_item = psz_var;
+            vlc_value_t val2;
+            while( *psz_var && *psz_var != ',' ) psz_var++;
+            if( *psz_var == ',' )
+            {
+                *psz_var = '\0';
+                psz_var++;
+            }
+            val2.i_int = strtol( psz_item, NULL, 0 );
+            INSERT_ELEM( p_list->p_values, p_list->i_count,
+                         p_list->i_count, val2 );
+            /* p_list->i_count is incremented twice by INSERT_ELEM */
+            p_list->i_count--;
+            INSERT_ELEM( p_list->pi_types, p_list->i_count,
+                         p_list->i_count, VLC_VAR_INTEGER );
+        }
+        if( psz_orig ) free( psz_orig );
+        break;
+    }
+
+    default:
+        goto cleanup;
+        break;
+    }
+
+    var_Set( p_obj, psz_name, val );
+
+  cleanup:
+    if( psz_name ) free( psz_name );
+    return;
+}
+
+
 /* Following functions are local */
 
 /*****************************************************************************