Commit a1e597bf authored by Clément Stenac's avatar Clément Stenac

* Make ParseOption (from input) a global service (var_OptionParse)

* Add i_options/pp_options to intf_Create

* add global options to enable file-logging and syslog (Refs:#508)
parent 71016b4e
......@@ -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.
*/
......
......@@ -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 * ) );
......
......@@ -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; \
......
......@@ -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 );
......
......@@ -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;
......
......@@ -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" ) )
......
......@@ -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.
......
......@@ -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 )
{
......
......@@ -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;
......
......@@ -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 );
......
......@@ -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 */
/*****************************************************************************
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment