* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
-#include <vlc/vlc.h>
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <vlc_common.h>
#include "../libvlc.h"
#include "vlc_charset.h"
#include "vlc_keys.h"
#include <errno.h> /* errno */
-
-#ifdef HAVE_LIMITS_H
-# include <limits.h>
+#include <assert.h>
+#include <limits.h>
+#ifdef __APPLE__
+# include <xlocale.h>
+#else
+#include <locale.h>
#endif
-#include "config.h"
+#include "configuration.h"
#include "modules/modules.h"
static char *ConfigKeyToString( int );
return src ? strdup (src) : NULL;
}
-static inline char *_strdupnull (const char *src)
+/**
+ * Get the user's configuration file
+ */
+static char *config_GetConfigFile( void )
{
- return src ? strdup (_(src)) : NULL;
-}
+ char *psz_dir = config_GetUserConfDir();
+ char *psz_configfile;
+ if( asprintf( &psz_configfile, "%s" DIR_SEP CONFIG_FILE, psz_dir ) == -1 )
+ psz_configfile = NULL;
+ free( psz_dir );
+ return psz_configfile;
+}
static FILE *config_OpenConfigFile( vlc_object_t *p_obj, const char *mode )
{
- char *psz_filename = p_obj->p_libvlc->psz_configfile;
+ char *psz_filename = libvlc_priv (p_obj->p_libvlc)->psz_configfile;
FILE *p_stream;
if( !psz_filename )
{
- psz_filename = config_GetConfigFile( p_obj->p_libvlc );
+ psz_filename = config_GetConfigFile();
}
msg_Dbg( p_obj, "opening config file (%s)", psz_filename );
* Specification configs */
char *psz_old;
if( asprintf( &psz_old, "%s" DIR_SEP CONFIG_DIR DIR_SEP CONFIG_FILE,
- p_obj->p_libvlc->psz_homedir ) != -1 )
+ config_GetHomeDir() ) != -1 )
{
p_stream = utf8_fopen( psz_old, mode );
if( p_stream )
"VLC will now use %s.", psz_old, psz_filename );
char *psz_readme;
if( asprintf(&psz_readme,"%s"DIR_SEP CONFIG_DIR DIR_SEP"README",
- p_obj->p_libvlc->psz_homedir ) != -1 )
+ config_GetHomeDir() ) != -1 )
{
FILE *p_readme = utf8_fopen( psz_readme, "wt" );
if( p_readme )
{
- fputs( "The VLC media player configuration folder has "
- "moved to comply with the XDG Base "
- "Directory Specification version 0.6. Your "
- "configuration has been copied to the new "
- "location (", p_readme );
- fputs( p_obj->p_libvlc->psz_configdir, p_readme );
- fputs( "). You can delete this directory and "
- "all its contents.", p_readme );
+ fprintf( p_readme, "The VLC media player "
+ "configuration folder has moved to comply\n"
+ "with the XDG Base Directory Specification "
+ "version 0.6. Your\nconfiguration has been "
+ "copied to the new location:\n%s\nYou can "
+ "delete this directory and all its contents.",
+ psz_filename);
fclose( p_readme );
}
free( psz_readme );
#endif
else if( p_stream != NULL )
{
- p_obj->p_libvlc->psz_configfile = psz_filename;
+ libvlc_priv (p_obj->p_libvlc)->psz_configfile = psz_filename;
}
return p_stream;
*****************************************************************************/
int __config_LoadConfigFile( vlc_object_t *p_this, const char *psz_module_name )
{
+ libvlc_priv_t *priv = libvlc_priv (p_this->p_libvlc);
vlc_list_t *p_list;
FILE *file;
return VLC_EGENERIC;
/* Acquire config file lock */
- vlc_mutex_lock( &p_this->p_libvlc->config_lock );
+ vlc_mutex_lock( &priv->config_lock );
/* Look for the selected module, if NULL then save everything */
p_list = vlc_list_find( p_this, VLC_OBJECT_MODULE, FIND_ANYWHERE );
char line[1024], section[1022];
section[0] = '\0';
+ /* Ensure consistent number formatting... */
+ locale_t loc = newlocale (LC_NUMERIC_MASK, "C", NULL);
+ locale_t baseloc = uselocale (loc);
+
while (fgets (line, 1024, file) != NULL)
{
/* Ignore comments and empty lines */
case CONFIG_ITEM_FLOAT:
if( !*psz_option_value )
break; /* ignore empty option */
- p_item->value.f = (float)i18n_atof( psz_option_value);
+ p_item->value.f = (float)atof (psz_option_value);
p_item->saved.f = p_item->value.f;
break;
fclose (file);
vlc_list_release( p_list );
+ if (loc != (locale_t)0)
+ {
+ uselocale (baseloc);
+ freelocale (loc);
+ }
- vlc_mutex_unlock( &p_this->p_libvlc->config_lock );
+ vlc_mutex_unlock( &priv->config_lock );
return 0;
}
*****************************************************************************/
int config_CreateDir( vlc_object_t *p_this, const char *psz_dirname )
{
- if( !psz_dirname && !*psz_dirname ) return -1;
+ if( !psz_dirname || !*psz_dirname ) return -1;
if( utf8_mkdir( psz_dirname, 0700 ) == 0 )
return 0;
return -1;
}
+static int
+config_Write (FILE *file, const char *type, const char *desc,
+ bool comment, const char *name, const char *fmt, ...)
+{
+ va_list ap;
+ int ret;
+
+ if (desc == NULL)
+ desc = "?";
+
+ if (fprintf (file, "# %s (%s)\n%s%s=", desc, _(type),
+ comment ? "#" : "", name) < 0)
+ return -1;
+
+ va_start (ap, fmt);
+ ret = vfprintf (file, fmt, ap);
+ va_end (ap);
+ if (ret < 0)
+ return -1;
+
+ if (fputs ("\n\n", file) == EOF)
+ return -1;
+ return 0;
+}
+
+
/*****************************************************************************
* config_SaveConfigFile: Save a module's config options.
*****************************************************************************
* Really stupid no ?
*****************************************************************************/
static int SaveConfigFile( vlc_object_t *p_this, const char *psz_module_name,
- vlc_bool_t b_autosave )
+ bool b_autosave )
{
+ libvlc_priv_t *priv = libvlc_priv (p_this->p_libvlc);
module_t *p_parser;
vlc_list_t *p_list;
FILE *file;
char p_line[1024], *p_index2;
int i_sizebuf = 0;
char *p_bigbuffer, *p_index;
- vlc_bool_t b_backup;
+ bool b_backup;
int i_index;
/* Acquire config file lock */
- vlc_mutex_lock( &p_this->p_libvlc->config_lock );
+ vlc_mutex_lock( &priv->config_lock );
- if( p_this->p_libvlc->psz_configfile == NULL )
+ if( libvlc_priv (p_this->p_libvlc)->psz_configfile == NULL )
{
- const char *psz_configdir = p_this->p_libvlc->psz_configdir;
+ char *psz_configdir = config_GetUserConfDir();
if( !psz_configdir ) /* XXX: This should never happen */
{
msg_Err( p_this, "no configuration directory defined" );
- vlc_mutex_unlock( &p_this->p_libvlc->config_lock );
+ vlc_mutex_unlock( &priv->config_lock );
return -1;
}
config_CreateDir( p_this, psz_configdir );
+ free( psz_configdir );
}
file = config_OpenConfigFile( p_this, "rt" );
p_bigbuffer = p_index = malloc( i_sizebuf+1 );
if( !p_bigbuffer )
{
- msg_Err( p_this, "out of memory" );
if( file ) fclose( file );
- vlc_mutex_unlock( &p_this->p_libvlc->config_lock );
+ vlc_mutex_unlock( &priv->config_lock );
return -1;
}
p_bigbuffer[0] = 0;
{
vlc_list_release( p_list );
free( p_bigbuffer );
- vlc_mutex_unlock( &p_this->p_libvlc->config_lock );
+ vlc_mutex_unlock( &priv->config_lock );
return -1;
}
fprintf( file, "\xEF\xBB\xBF###\n### " COPYRIGHT_MESSAGE "\n###\n\n"
- "###\n### lines begining with a '#' character are comments\n###\n\n" );
+ "###\n### lines beginning with a '#' character are comments\n###\n\n" );
+
+ /* Ensure consistent number formatting... */
+ locale_t loc = newlocale (LC_NUMERIC_MASK, "C", NULL);
+ locale_t baseloc = uselocale (loc);
/* Look for the selected module, if NULL then save everything */
for( i_index = 0; i_index < p_list->i_count; i_index++ )
p_item < p_end;
p_item++ )
{
- char *psz_key;
- int i_value = p_item->value.i;
- float f_value = p_item->value.f;
- const char *psz_value = p_item->value.psz;
+ /* Do not save the new value in the configuration file
+ * if doing an autosave, and the item is not an "autosaved" one. */
+ bool b_retain = b_autosave && !p_item->b_autosave;
- if( p_item->i_type & CONFIG_HINT )
- /* ignore hints */
- continue;
- /* Ignore deprecated options */
- if( p_item->psz_current )
- continue;
- if( p_item->b_unsaveable )
- /*obvious*/
+ if ((p_item->i_type & CONFIG_HINT) /* ignore hint */
+ || p_item->b_removed /* ignore deprecated option */
+ || p_item->b_unsaveable) /* ignore volatile option */
continue;
- if( b_autosave && !p_item->b_autosave )
+ if (IsConfigIntegerType (p_item->i_type))
{
- i_value = p_item->saved.i;
- f_value = p_item->saved.f;
- psz_value = p_item->saved.psz;
- if( !psz_value ) psz_value = p_item->orig.psz;
+ int val = b_retain ? p_item->saved.i : p_item->value.i;
+ if (p_item->i_type == CONFIG_ITEM_KEY)
+ {
+ char *psz_key = ConfigKeyToString (val);
+ config_Write (file, p_item->psz_text, N_("key"),
+ val == p_item->orig.i,
+ p_item->psz_name, "%s",
+ psz_key ? psz_key : "");
+ free (psz_key);
+ }
+ else
+ config_Write (file, p_item->psz_text,
+ (p_item->i_type == CONFIG_ITEM_BOOL)
+ ? N_("boolean") : N_("integer"),
+ val == p_item->orig.i,
+ p_item->psz_name, "%d", val);
+ p_item->saved.i = val;
}
else
+ if (IsConfigFloatType (p_item->i_type))
{
- p_item->b_dirty = VLC_FALSE;
+ float val = b_retain ? p_item->saved.f : p_item->value.f;
+ config_Write (file, p_item->psz_text, N_("float"),
+ val == p_item->orig.f,
+ p_item->psz_name, "%f", val);
+ p_item->saved.f = val;
}
-
- switch( p_item->i_type )
+ else
{
- case CONFIG_ITEM_BOOL:
- case CONFIG_ITEM_INTEGER:
- if( p_item->psz_text )
- fprintf( file, "# %s (%s)\n", p_item->psz_text,
- (p_item->i_type == CONFIG_ITEM_BOOL) ?
- _("boolean") : _("integer") );
- if( i_value == p_item->orig.i )
- fputc ('#', file);
- fprintf( file, "%s=%i\n", p_item->psz_name, i_value );
-
- p_item->saved.i = i_value;
- break;
-
- case CONFIG_ITEM_KEY:
- if( p_item->psz_text )
- fprintf( file, "# %s (%s)\n", p_item->psz_text,
- _("key") );
- if( i_value == p_item->orig.i )
- fputc ('#', file);
- psz_key = ConfigKeyToString( i_value );
- fprintf( file, "%s=%s\n", p_item->psz_name,
- psz_key ? psz_key : "" );
- free (psz_key);
-
- p_item->saved.i = i_value;
- break;
-
- case CONFIG_ITEM_FLOAT:
- if( p_item->psz_text )
- fprintf( file, "# %s (%s)\n", p_item->psz_text,
- _("float") );
- if( f_value == p_item->orig.f )
- fputc ('#', file);
- fprintf( file, "%s=%f\n", p_item->psz_name, (double)f_value );
-
- p_item->saved.f = f_value;
- break;
-
- default:
- if( p_item->psz_text )
- fprintf( file, "# %s (%s)\n", p_item->psz_text,
- _("string") );
- if( (!psz_value && !p_item->orig.psz) ||
- (psz_value && p_item->orig.psz &&
- !strcmp( psz_value, p_item->orig.psz )) )
- fputc ('#', file);
- fprintf( file, "%s=%s\n", p_item->psz_name,
- psz_value ?: "" );
-
- if( b_autosave && !p_item->b_autosave ) break;
-
- free ((char *)p_item->saved.psz);
- if( (psz_value && p_item->orig.psz &&
- strcmp( psz_value, p_item->orig.psz )) ||
- !psz_value || !p_item->orig.psz)
- p_item->saved.psz = strdupnull (psz_value);
- else
- p_item->saved.psz = NULL;
+ const char *psz_value = b_retain ? p_item->saved.psz
+ : p_item->value.psz;
+ bool modified;
+
+ assert (IsConfigStringType (p_item->i_type));
+
+ if (b_retain && (psz_value == NULL)) /* FIXME: hack */
+ psz_value = p_item->orig.psz;
+
+ modified =
+ (psz_value != NULL)
+ ? ((p_item->orig.psz != NULL)
+ ? (strcmp (psz_value, p_item->orig.psz) != 0)
+ : true)
+ : (p_item->orig.psz != NULL);
+
+ config_Write (file, p_item->psz_text, N_("string"),
+ !modified, p_item->psz_name, "%s",
+ psz_value ? psz_value : "");
+
+ if ( !b_retain )
+ {
+
+ free ((char *)p_item->saved.psz);
+ if( (psz_value && p_item->orig.psz &&
+ strcmp( psz_value, p_item->orig.psz )) ||
+ !psz_value || !p_item->orig.psz)
+ p_item->saved.psz = strdupnull (psz_value);
+ else
+ p_item->saved.psz = NULL;
+ }
}
- }
- fputc ('\n', file);
+ if (!b_retain)
+ p_item->b_dirty = false;
+ }
}
vlc_list_release( p_list );
+ if (loc != (locale_t)0)
+ {
+ uselocale (baseloc);
+ freelocale (loc);
+ }
/*
* Restore old settings from the config in file
free( p_bigbuffer );
fclose( file );
- vlc_mutex_unlock( &p_this->p_libvlc->config_lock );
+ vlc_mutex_unlock( &priv->config_lock );
return 0;
}
int config_AutoSaveConfigFile( vlc_object_t *p_this )
{
+ libvlc_priv_t *priv = libvlc_priv (p_this->p_libvlc);
vlc_list_t *p_list;
int i_index, i_count;
- if( !p_this ) return -1;
+ assert( p_this );
/* Check if there's anything to save */
- vlc_mutex_lock( &p_this->p_libvlc->config_lock );
+ vlc_mutex_lock( &priv->config_lock );
p_list = vlc_list_find( p_this, VLC_OBJECT_MODULE, FIND_ANYWHERE );
i_count = p_list->i_count;
for( i_index = 0; i_index < i_count; i_index++ )
{
if( p_item->b_autosave && p_item->b_dirty ) break;
}
- break;
+ if( p_item < p_end ) break;
}
vlc_list_release( p_list );
- vlc_mutex_unlock( &p_this->p_libvlc->config_lock );
+ vlc_mutex_unlock( &priv->config_lock );
if( i_index == i_count ) return VLC_SUCCESS;
- return SaveConfigFile( p_this, 0, VLC_TRUE );
+ return SaveConfigFile( p_this, 0, true );
}
int __config_SaveConfigFile( vlc_object_t *p_this, const char *psz_module_name )
{
- return SaveConfigFile( p_this, psz_module_name, VLC_FALSE );
-}
-
-/**
- * Get the user's configuration file
- */
-char *config_GetConfigFile( libvlc_int_t *p_libvlc )
-{
- char *psz_configfile;
- if( asprintf( &psz_configfile, "%s" DIR_SEP CONFIG_FILE,
- p_libvlc->psz_configdir ) == -1 )
- return NULL;
- return psz_configfile;
+ return SaveConfigFile( p_this, psz_module_name, false );
}
/**
{
/* This is incomplete: we should also support the ~cmassiot/ syntax */
char *psz_buf;
- if( asprintf( &psz_buf, "%s/%s", p_libvlc->psz_homedir,
+ if( asprintf( &psz_buf, "%s/%s", config_GetHomeDir(),
psz_configfile + 2 ) == -1 )
{
free( psz_configfile );