1 /*****************************************************************************
2 * core.c management of the modules configuration
3 *****************************************************************************
4 * Copyright (C) 2001-2007 VLC authors and VideoLAN
7 * Authors: Gildas Bazin <gbazin@videolan.org>
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU Lesser General Public License as published by
11 * the Free Software Foundation; either version 2.1 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public License
20 * along with this program; if not, write to the Free Software Foundation,
21 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22 *****************************************************************************/
28 #include <vlc_common.h>
30 #include <vlc_modules.h>
31 #include <vlc_plugin.h>
33 #include "vlc_configuration.h"
37 #include "configuration.h"
38 #include "modules/modules.h"
40 vlc_rwlock_t config_lock = VLC_STATIC_RWLOCK;
42 static inline char *strdupnull (const char *src)
44 return src ? strdup (src) : NULL;
48 /*****************************************************************************
49 * config_GetType: get the type of a variable (bool, int, float, string)
50 *****************************************************************************
51 * This function is used to get the type of a variable from its name.
52 * Beware, this is quite slow.
53 *****************************************************************************/
54 int config_GetType( vlc_object_t *p_this, const char *psz_name )
56 module_config_t *p_config;
59 p_config = config_FindConfig( p_this, psz_name );
67 switch( CONFIG_CLASS(p_config->i_type) )
69 case CONFIG_ITEM_FLOAT:
70 i_type = VLC_VAR_FLOAT;
73 case CONFIG_ITEM_INTEGER:
74 i_type = VLC_VAR_INTEGER;
77 case CONFIG_ITEM_BOOL:
78 i_type = VLC_VAR_BOOL;
81 case CONFIG_ITEM_STRING:
82 i_type = VLC_VAR_STRING;
93 bool config_IsSafe( const char *name )
95 module_config_t *p_config = config_FindConfig( NULL, name );
96 return p_config != NULL && p_config->b_safe;
100 /*****************************************************************************
101 * config_GetInt: get the value of an int variable
102 *****************************************************************************
103 * This function is used to get the value of variables which are internally
104 * represented by an integer (CONFIG_ITEM_INTEGER and
106 *****************************************************************************/
107 int64_t config_GetInt( vlc_object_t *p_this, const char *psz_name )
109 module_config_t *p_config;
111 p_config = config_FindConfig( p_this, psz_name );
116 msg_Err( p_this, "option %s does not exist", psz_name );
120 if (!IsConfigIntegerType (p_config->i_type))
122 msg_Err( p_this, "option %s does not refer to an int", psz_name );
128 vlc_rwlock_rdlock (&config_lock);
129 val = p_config->value.i;
130 vlc_rwlock_unlock (&config_lock);
134 #undef config_GetFloat
135 /*****************************************************************************
136 * config_GetFloat: get the value of a float variable
137 *****************************************************************************
138 * This function is used to get the value of variables which are internally
139 * represented by a float (CONFIG_ITEM_FLOAT).
140 *****************************************************************************/
141 float config_GetFloat( vlc_object_t *p_this, const char *psz_name )
143 module_config_t *p_config;
145 p_config = config_FindConfig( p_this, psz_name );
150 msg_Err( p_this, "option %s does not exist", psz_name );
154 if (!IsConfigFloatType (p_config->i_type))
156 msg_Err( p_this, "option %s does not refer to a float", psz_name );
162 vlc_rwlock_rdlock (&config_lock);
163 val = p_config->value.f;
164 vlc_rwlock_unlock (&config_lock);
169 /*****************************************************************************
170 * config_GetPsz: get the string value of a string variable
171 *****************************************************************************
172 * This function is used to get the value of variables which are internally
173 * represented by a string (CONFIG_ITEM_STRING, CONFIG_ITEM_*FILE,
174 * CONFIG_ITEM_DIRECTORY, CONFIG_ITEM_PASSWORD, and CONFIG_ITEM_MODULE).
176 * Important note: remember to free() the returned char* because it's a
177 * duplicate of the actual value. It isn't safe to return a pointer to the
178 * actual value as it can be modified at any time.
179 *****************************************************************************/
180 char * config_GetPsz( vlc_object_t *p_this, const char *psz_name )
182 module_config_t *p_config;
184 p_config = config_FindConfig( p_this, psz_name );
189 msg_Err( p_this, "option %s does not exist", psz_name );
193 if (!IsConfigStringType (p_config->i_type))
195 msg_Err( p_this, "option %s does not refer to a string", psz_name );
199 /* return a copy of the string */
200 vlc_rwlock_rdlock (&config_lock);
201 char *psz_value = strdupnull (p_config->value.psz);
202 vlc_rwlock_unlock (&config_lock);
208 /*****************************************************************************
209 * config_PutPsz: set the string value of a string variable
210 *****************************************************************************
211 * This function is used to set the value of variables which are internally
212 * represented by a string (CONFIG_ITEM_STRING, CONFIG_ITEM_*FILE,
213 * CONFIG_ITEM_DIRECTORY, CONFIG_ITEM_PASSWORD, and CONFIG_ITEM_MODULE).
214 *****************************************************************************/
215 void config_PutPsz( vlc_object_t *p_this,
216 const char *psz_name, const char *psz_value )
218 module_config_t *p_config;
220 p_config = config_FindConfig( p_this, psz_name );
226 msg_Warn( p_this, "option %s does not exist", psz_name );
230 if (!IsConfigStringType (p_config->i_type))
232 msg_Err( p_this, "option %s does not refer to a string", psz_name );
237 if ((psz_value != NULL) && *psz_value)
238 str = strdup (psz_value);
242 vlc_rwlock_wrlock (&config_lock);
243 oldstr = (char *)p_config->value.psz;
244 p_config->value.psz = str;
245 p_config->b_dirty = true;
246 vlc_rwlock_unlock (&config_lock);
252 /*****************************************************************************
253 * config_PutInt: set the integer value of an int variable
254 *****************************************************************************
255 * This function is used to set the value of variables which are internally
256 * represented by an integer (CONFIG_ITEM_INTEGER and
258 *****************************************************************************/
259 void config_PutInt( vlc_object_t *p_this, const char *psz_name,
262 module_config_t *p_config;
264 p_config = config_FindConfig( p_this, psz_name );
269 msg_Warn( p_this, "option %s does not exist", psz_name );
273 if (!IsConfigIntegerType (p_config->i_type))
275 msg_Err( p_this, "option %s does not refer to an int", psz_name );
279 if (i_value < p_config->min.i)
280 i_value = p_config->min.i;
281 if (i_value > p_config->max.i)
282 i_value = p_config->max.i;
284 vlc_rwlock_wrlock (&config_lock);
285 p_config->value.i = i_value;
286 p_config->b_dirty = true;
287 vlc_rwlock_unlock (&config_lock);
290 #undef config_PutFloat
291 /*****************************************************************************
292 * config_PutFloat: set the value of a float variable
293 *****************************************************************************
294 * This function is used to set the value of variables which are internally
295 * represented by a float (CONFIG_ITEM_FLOAT).
296 *****************************************************************************/
297 void config_PutFloat( vlc_object_t *p_this,
298 const char *psz_name, float f_value )
300 module_config_t *p_config;
302 p_config = config_FindConfig( p_this, psz_name );
307 msg_Warn( p_this, "option %s does not exist", psz_name );
311 if (!IsConfigFloatType (p_config->i_type))
313 msg_Err( p_this, "option %s does not refer to a float", psz_name );
317 /* if f_min == f_max == 0, then do not use them */
318 if ((p_config->min.f == 0) && (p_config->max.f == 0))
320 else if (f_value < p_config->min.f)
321 f_value = p_config->min.f;
322 else if (f_value > p_config->max.f)
323 f_value = p_config->max.f;
325 vlc_rwlock_wrlock (&config_lock);
326 p_config->value.f = f_value;
327 p_config->b_dirty = true;
328 vlc_rwlock_unlock (&config_lock);
331 static int confcmp (const void *a, const void *b)
333 const module_config_t *const *ca = a, *const *cb = b;
335 return strcmp ((*ca)->psz_name, (*cb)->psz_name);
338 static int confnamecmp (const void *key, const void *elem)
340 const module_config_t *const *conf = elem;
342 return strcmp (key, (*conf)->psz_name);
347 module_config_t **list;
349 } config = { NULL, 0 };
352 * Index the configuration items by name for faster lookups.
354 int config_SortConfig (void)
357 module_t **mlist = module_list_get (&nmod);
358 if (unlikely(mlist == NULL))
362 for (size_t i = 0; i < nmod; i++)
363 nconf += mlist[i]->confsize;
365 module_config_t **clist = malloc (sizeof (*clist) * nconf);
366 if (unlikely(clist == NULL))
368 module_list_free (mlist);
373 for (size_t i = 0; i < nmod; i++)
375 module_t *parser = mlist[i];
376 module_config_t *item, *end;
378 for (item = parser->p_config, end = item + parser->confsize;
382 if (!CONFIG_ITEM(item->i_type))
383 continue; /* ignore hints */
384 clist[nconf++] = item;
387 module_list_free (mlist);
389 qsort (clist, nconf, sizeof (*clist), confcmp);
392 config.count = nconf;
396 void config_UnsortConfig (void)
398 module_config_t **clist;
407 /*****************************************************************************
408 * config_FindConfig: find the config structure associated with an option.
409 *****************************************************************************
410 * FIXME: remove p_this pointer parameter (or use it)
411 *****************************************************************************/
412 module_config_t *config_FindConfig (vlc_object_t *p_this, const char *name)
416 if (unlikely(name == NULL))
419 module_config_t *const *p;
420 p = bsearch (name, config.list, config.count, sizeof (*p), confnamecmp);
421 return p ? *p : NULL;
425 * Destroys an array of configuration items.
426 * \param config start of array of items
427 * \param confsize number of items in the array
429 void config_Free (module_config_t *config, size_t confsize)
431 for (size_t j = 0; j < confsize; j++)
433 module_config_t *p_item = config + j;
435 free( p_item->psz_type );
436 free( p_item->psz_name );
437 free( p_item->psz_text );
438 free( p_item->psz_longtext );
440 if (IsConfigStringType (p_item->i_type))
442 free (p_item->value.psz);
443 free (p_item->orig.psz);
446 if( p_item->ppsz_list )
447 for (int i = 0; i < p_item->i_list; i++)
448 free( p_item->ppsz_list[i] );
449 if( p_item->ppsz_list_text )
450 for (int i = 0; i < p_item->i_list; i++)
451 free( p_item->ppsz_list_text[i] );
452 free( p_item->ppsz_list );
453 free( p_item->ppsz_list_text );
454 free( p_item->pi_list );
456 if( p_item->i_action )
458 for (int i = 0; i < p_item->i_action; i++)
459 free( p_item->ppsz_action_text[i] );
460 free( p_item->ppf_action );
461 free( p_item->ppsz_action_text );
468 #undef config_ResetAll
469 /*****************************************************************************
470 * config_ResetAll: reset the configuration data for all the modules.
471 *****************************************************************************/
472 void config_ResetAll( vlc_object_t *p_this )
476 module_t **list = module_list_get (NULL);
478 vlc_rwlock_wrlock (&config_lock);
479 for (size_t j = 0; (p_module = list[j]) != NULL; j++)
480 for (size_t i = 0; i < p_module->confsize; i++ )
482 module_config_t *p_config = p_module->p_config + i;
484 if (IsConfigIntegerType (p_config->i_type))
485 p_config->value.i = p_config->orig.i;
487 if (IsConfigFloatType (p_config->i_type))
488 p_config->value.f = p_config->orig.f;
490 if (IsConfigStringType (p_config->i_type))
492 free ((char *)p_config->value.psz);
493 p_config->value.psz =
494 strdupnull (p_config->orig.psz);
497 vlc_rwlock_unlock (&config_lock);
499 module_list_free (list);