Commit e9d7d37c authored by Rémi Denis-Courmont's avatar Rémi Denis-Courmont

Read configuration file in a single pass (instead of one per module).

(I get about hundred time faster config load here, but right, there are
 much slower operations in libvlc startup anyway
 -- and the plugin cache breakage is not going to help).
parent 07376930
...@@ -808,8 +808,6 @@ int __config_LoadConfigFile( vlc_object_t *p_this, const char *psz_module_name ) ...@@ -808,8 +808,6 @@ int __config_LoadConfigFile( vlc_object_t *p_this, const char *psz_module_name )
{ {
vlc_list_t *p_list; vlc_list_t *p_list;
FILE *file; FILE *file;
char *p_index;
int i_index;
file = config_OpenConfigFile (p_this, "rt"); file = config_OpenConfigFile (p_this, "rt");
if (file == NULL) if (file == NULL)
...@@ -821,91 +819,92 @@ int __config_LoadConfigFile( vlc_object_t *p_this, const char *psz_module_name ) ...@@ -821,91 +819,92 @@ int __config_LoadConfigFile( vlc_object_t *p_this, const char *psz_module_name )
/* Look for the selected module, if NULL then save everything */ /* Look for the selected module, if NULL then save everything */
p_list = vlc_list_find( p_this, VLC_OBJECT_MODULE, FIND_ANYWHERE ); p_list = vlc_list_find( p_this, VLC_OBJECT_MODULE, FIND_ANYWHERE );
for( i_index = 0; i_index < p_list->i_count; i_index++ ) /* Look for UTF-8 Byte Order Mark */
char * (*convert) (const char *) = strdupnull;
char bom[3];
if ((fread (bom, 1, 3, file) != 3)
|| memcmp (bom, "\xEF\xBB\xBF", 3))
{ {
module_t *p_parser = (module_t *)p_list->p_values[i_index].p_object ; convert = FromLocaleDup;
char line[1024]; rewind (file); // no BOM, rewind
}
if( psz_module_name module_t *module = NULL;
&& strcmp( psz_module_name, p_parser->psz_object_name ) ) char line[1024], section[1022];
section[0] = '\0';
while (fgets (line, 1024, file) != NULL)
{
// Ignore comments and empty lines
switch (line[0])
{ {
case '#':
case '\n':
case '\0':
continue; continue;
} }
/* The config file is organized in sections, one per module. Look for if (line[0] == '[')
* the interesting section ( a section is of the form [foo] ) */ {
fseek( file, 0L, SEEK_SET ); char *ptr = strchr (line, ']');
if (ptr == NULL)
/* Look for UTF-8 Byte Order Mark */ continue; // syntax error;
char * (*convert) (const char *) = FromLocaleDup; *ptr = '\0';
char bom[3];
if ((fread (bom, 1, 3, file) == 3) // New section ( = a given module)
&& (memcmp (bom, "\xEF\xBB\xBF", 3) == 0)) strcpy (section, line + 1);
convert = strdupnull; module = NULL;
else
rewind (file); // no BOM, rewind
while( fgets( line, 1024, file ) ) if ((psz_module_name == NULL)
|| (strcmp (psz_module_name, section) == 0))
{ {
if( (line[0] == '[') for (int i = 0; i < p_list->i_count; i++)
&& (p_index = strchr(line,']'))
&& (p_index - &line[1]
== (int)strlen(p_parser->psz_object_name))
&& !memcmp( &line[1], p_parser->psz_object_name,
strlen(p_parser->psz_object_name) ) )
{ {
#if 0 module_t *m = (module_t *)p_list->p_values[i].p_object;
msg_Dbg( p_this, "loading config for module \"%s\"",
p_parser->psz_object_name );
#endif
if ((strcmp (section, m->psz_object_name) == 0)
&& (m->i_config_items > 0)) // ignore config-less modules
{
module = m;
if (psz_module_name != NULL)
msg_Dbg (p_this,
"loading config for module \"%s\"",
section);
break; break;
} }
} }
/* either we found the section or we're at the EOF */ }
/* Now try to load the options in this section */
while( fgets( line, 1024, file ) )
{
const char *psz_option_name, *psz_option_value;
module_config_t *p_item, *p_end;
if( line[0] == '[' ) break; /* end of section */
/* ignore comments or empty lines */
if( (line[0] == '#') || (line[0] == '\n') || (line[0] == (char)0) )
continue; continue;
}
if (module == NULL)
continue; // no need to parse if there is no matching module
/* get rid of line feed */ char *ptr = strchr (line, '\n');
if( line[strlen(line)-1] == '\n' ) if (ptr != NULL)
line[strlen(line)-1] = (char)0; *ptr = '\0';
/* look for option name */ /* look for option name */
psz_option_name = line; const char *psz_option_name = line;
psz_option_value = NULL;
p_index = strchr( line, '=' );
if( !p_index ) break; /* this ain't an option!!! */
*p_index = (char)0; ptr = strchr (line, '=');
psz_option_value = p_index + 1; if (ptr == NULL)
continue; // syntax error
if( !p_parser->i_config_items ) *ptr = '\0';
{ const char *psz_option_value = ptr + 1;
continue;
}
/* try to match this option with one of the module's options */ /* try to match this option with one of the module's options */
for( p_item = p_parser->p_config, p_end = p_item + p_parser->confsize; for (size_t i = 0; i < module->confsize; i++)
p_item < p_end;
p_item++ )
{ {
if( p_item->i_type & CONFIG_HINT ) module_config_t *p_item = module->p_config + i;
/* ignore hints */
if ((p_item->i_type & CONFIG_HINT)
|| strcmp (p_item->psz_name, psz_option_name))
continue; continue;
if( !strcmp( p_item->psz_name, psz_option_name ) )
{
/* We found it */ /* We found it */
switch( p_item->i_type ) switch( p_item->i_type )
{ {
...@@ -915,10 +914,9 @@ int __config_LoadConfigFile( vlc_object_t *p_this, const char *psz_module_name ) ...@@ -915,10 +914,9 @@ int __config_LoadConfigFile( vlc_object_t *p_this, const char *psz_module_name )
break; /* ignore empty option */ break; /* ignore empty option */
p_item->value.i = strtol( psz_option_value, 0, 0 ); p_item->value.i = strtol( psz_option_value, 0, 0 );
p_item->saved.i = p_item->value.i; p_item->saved.i = p_item->value.i;
#if 0
msg_Dbg( p_this, "option \"%s\", value %i", /*msg_Dbg (p_this, "option \"%s\", value %i",
p_item->psz_name, p_item->i_value ); psz_option_name, p_item->value.i);*/
#endif
break; break;
case CONFIG_ITEM_FLOAT: case CONFIG_ITEM_FLOAT:
...@@ -926,11 +924,11 @@ int __config_LoadConfigFile( vlc_object_t *p_this, const char *psz_module_name ) ...@@ -926,11 +924,11 @@ int __config_LoadConfigFile( vlc_object_t *p_this, const char *psz_module_name )
break; /* ignore empty option */ break; /* ignore empty option */
p_item->value.f = (float)i18n_atof( psz_option_value); p_item->value.f = (float)i18n_atof( psz_option_value);
p_item->saved.f = p_item->value.f; p_item->saved.f = p_item->value.f;
#if 0
msg_Dbg( p_this, "option \"%s\", value %f", /*msg_Dbg (p_this, "option \"%s\", value %f",
p_item->psz_name, (double)p_item->f_value ); psz_option_name, (double)p_item->value.f);*/
#endif
break; break;
case CONFIG_ITEM_KEY: case CONFIG_ITEM_KEY:
if( !*psz_option_value ) if( !*psz_option_value )
break; /* ignore empty option */ break; /* ignore empty option */
...@@ -942,31 +940,21 @@ int __config_LoadConfigFile( vlc_object_t *p_this, const char *psz_module_name ) ...@@ -942,31 +940,21 @@ int __config_LoadConfigFile( vlc_object_t *p_this, const char *psz_module_name )
vlc_mutex_lock( p_item->p_lock ); vlc_mutex_lock( p_item->p_lock );
/* free old string */ /* free old string */
freenull (p_item->value.psz); free (p_item->value.psz);
free (p_item->saved.psz);
p_item->value.psz = convert (psz_option_value); p_item->value.psz = convert (psz_option_value);
p_item->saved.psz = strdupnull (p_item->value.psz);
freenull (p_item->saved.psz);
p_item->saved.psz = NULL;
if( !p_item->value.psz || !p_item->orig.psz ||
(p_item->value.psz && p_item->orig.psz &&
strcmp(p_item->value.psz, p_item->orig.psz)))
p_item->saved.psz = convert (p_item->value.psz);
vlc_mutex_unlock( p_item->p_lock ); vlc_mutex_unlock( p_item->p_lock );
#if 0 /*msg_Dbg (p_this, "option \"%s\", value \"%s\"",
msg_Dbg( p_this, "option \"%s\", value \"%s\"", psz_option_name, psz_option_value ?: "");*/
p_item->psz_name,
p_item->psz_value ? p_item->psz_value : "" );
#endif
break; break;
} }
}
}
}
break;
}
} }
vlc_list_release( p_list ); vlc_list_release( p_list );
......
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