1 /*****************************************************************************
2 * core.c management of the modules configuration
3 *****************************************************************************
4 * Copyright (C) 2001-2007 the VideoLAN team
7 * Authors: Gildas Bazin <gbazin@videolan.org>
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 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 General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22 *****************************************************************************/
28 #include <vlc_common.h>
30 #include <vlc_modules.h>
32 #include "vlc_configuration.h"
36 #include "configuration.h"
37 #include "modules/modules.h"
39 vlc_rwlock_t config_lock = VLC_STATIC_RWLOCK;
41 static inline char *strdupnull (const char *src)
43 return src ? strdup (src) : NULL;
47 /*****************************************************************************
48 * config_GetType: get the type of a variable (bool, int, float, string)
49 *****************************************************************************
50 * This function is used to get the type of a variable from its name.
51 * Beware, this is quite slow.
52 *****************************************************************************/
53 int config_GetType( vlc_object_t *p_this, const char *psz_name )
55 module_config_t *p_config;
58 p_config = config_FindConfig( p_this, psz_name );
66 switch( CONFIG_CLASS(p_config->i_type) )
68 case CONFIG_ITEM_FLOAT:
69 i_type = VLC_VAR_FLOAT;
72 case CONFIG_ITEM_INTEGER:
73 i_type = VLC_VAR_INTEGER;
76 case CONFIG_ITEM_BOOL:
77 i_type = VLC_VAR_BOOL;
80 case CONFIG_ITEM_STRING:
81 i_type = VLC_VAR_STRING;
92 bool config_IsSafe( const char *name )
94 module_config_t *p_config = config_FindConfig( NULL, name );
95 return p_config != NULL && p_config->b_safe;
99 /*****************************************************************************
100 * config_GetInt: get the value of an int variable
101 *****************************************************************************
102 * This function is used to get the value of variables which are internally
103 * represented by an integer (CONFIG_ITEM_INTEGER and
105 *****************************************************************************/
106 int64_t config_GetInt( vlc_object_t *p_this, const char *psz_name )
108 module_config_t *p_config;
110 p_config = config_FindConfig( p_this, psz_name );
115 msg_Err( p_this, "option %s does not exist", psz_name );
119 if (!IsConfigIntegerType (p_config->i_type))
121 msg_Err( p_this, "option %s does not refer to an int", psz_name );
127 vlc_rwlock_rdlock (&config_lock);
128 val = p_config->value.i;
129 vlc_rwlock_unlock (&config_lock);
133 #undef config_GetFloat
134 /*****************************************************************************
135 * config_GetFloat: get the value of a float variable
136 *****************************************************************************
137 * This function is used to get the value of variables which are internally
138 * represented by a float (CONFIG_ITEM_FLOAT).
139 *****************************************************************************/
140 float config_GetFloat( vlc_object_t *p_this, const char *psz_name )
142 module_config_t *p_config;
144 p_config = config_FindConfig( p_this, psz_name );
149 msg_Err( p_this, "option %s does not exist", psz_name );
153 if (!IsConfigFloatType (p_config->i_type))
155 msg_Err( p_this, "option %s does not refer to a float", psz_name );
161 vlc_rwlock_rdlock (&config_lock);
162 val = p_config->value.f;
163 vlc_rwlock_unlock (&config_lock);
168 /*****************************************************************************
169 * config_GetPsz: get the string value of a string variable
170 *****************************************************************************
171 * This function is used to get the value of variables which are internally
172 * represented by a string (CONFIG_ITEM_STRING, CONFIG_ITEM_*FILE,
173 * CONFIG_ITEM_DIRECTORY, CONFIG_ITEM_PASSWORD, and CONFIG_ITEM_MODULE).
175 * Important note: remember to free() the returned char* because it's a
176 * duplicate of the actual value. It isn't safe to return a pointer to the
177 * actual value as it can be modified at any time.
178 *****************************************************************************/
179 char * config_GetPsz( vlc_object_t *p_this, const char *psz_name )
181 module_config_t *p_config;
183 p_config = config_FindConfig( p_this, psz_name );
188 msg_Err( p_this, "option %s does not exist", psz_name );
192 if (!IsConfigStringType (p_config->i_type))
194 msg_Err( p_this, "option %s does not refer to a string", psz_name );
198 /* return a copy of the string */
199 vlc_rwlock_rdlock (&config_lock);
200 char *psz_value = strdupnull (p_config->value.psz);
201 vlc_rwlock_unlock (&config_lock);
207 /*****************************************************************************
208 * config_PutPsz: set the string value of a string variable
209 *****************************************************************************
210 * This function is used to set the value of variables which are internally
211 * represented by a string (CONFIG_ITEM_STRING, CONFIG_ITEM_*FILE,
212 * CONFIG_ITEM_DIRECTORY, CONFIG_ITEM_PASSWORD, and CONFIG_ITEM_MODULE).
213 *****************************************************************************/
214 void config_PutPsz( vlc_object_t *p_this,
215 const char *psz_name, const char *psz_value )
217 module_config_t *p_config;
219 p_config = config_FindConfig( p_this, psz_name );
225 msg_Warn( p_this, "option %s does not exist", psz_name );
229 if (!IsConfigStringType (p_config->i_type))
231 msg_Err( p_this, "option %s does not refer to a string", psz_name );
236 if ((psz_value != NULL) && *psz_value)
237 str = strdup (psz_value);
241 vlc_rwlock_wrlock (&config_lock);
242 oldstr = (char *)p_config->value.psz;
243 p_config->value.psz = str;
244 p_config->b_dirty = true;
245 vlc_rwlock_unlock (&config_lock);
251 /*****************************************************************************
252 * config_PutInt: set the integer value of an int variable
253 *****************************************************************************
254 * This function is used to set the value of variables which are internally
255 * represented by an integer (CONFIG_ITEM_INTEGER and
257 *****************************************************************************/
258 void config_PutInt( vlc_object_t *p_this, const char *psz_name,
261 module_config_t *p_config;
263 p_config = config_FindConfig( p_this, psz_name );
268 msg_Warn( p_this, "option %s does not exist", psz_name );
272 if (!IsConfigIntegerType (p_config->i_type))
274 msg_Err( p_this, "option %s does not refer to an int", psz_name );
278 if (i_value < p_config->min.i)
279 i_value = p_config->min.i;
280 if (i_value > p_config->max.i)
281 i_value = p_config->max.i;
283 vlc_rwlock_wrlock (&config_lock);
284 p_config->value.i = i_value;
285 p_config->b_dirty = true;
286 vlc_rwlock_unlock (&config_lock);
289 #undef config_PutFloat
290 /*****************************************************************************
291 * config_PutFloat: set the value of a float variable
292 *****************************************************************************
293 * This function is used to set the value of variables which are internally
294 * represented by a float (CONFIG_ITEM_FLOAT).
295 *****************************************************************************/
296 void config_PutFloat( vlc_object_t *p_this,
297 const char *psz_name, float f_value )
299 module_config_t *p_config;
301 p_config = config_FindConfig( p_this, psz_name );
306 msg_Warn( p_this, "option %s does not exist", psz_name );
310 if (!IsConfigFloatType (p_config->i_type))
312 msg_Err( p_this, "option %s does not refer to a float", psz_name );
316 /* if f_min == f_max == 0, then do not use them */
317 if ((p_config->min.f == 0) && (p_config->max.f == 0))
319 else if (f_value < p_config->min.f)
320 f_value = p_config->min.f;
321 else if (f_value > p_config->max.f)
322 f_value = p_config->max.f;
324 vlc_rwlock_wrlock (&config_lock);
325 p_config->value.f = f_value;
326 p_config->b_dirty = true;
327 vlc_rwlock_unlock (&config_lock);
330 static int confcmp (const void *a, const void *b)
332 const module_config_t *const *ca = a, *const *cb = b;
334 return strcmp ((*ca)->psz_name, (*cb)->psz_name);
337 static int confnamecmp (const void *key, const void *elem)
339 const module_config_t *const *conf = elem;
341 return strcmp (key, (*conf)->psz_name);
346 module_config_t **list;
348 } config = { NULL, 0 };
351 * Index the configuration items by name for faster lookups.
353 int config_SortConfig (void)
356 module_t **mlist = module_list_get (&nmod);
357 if (unlikely(mlist == NULL))
361 for (size_t i = 0; i < nmod; i++)
362 nconf += mlist[i]->confsize;
364 module_config_t **clist = malloc (sizeof (*clist) * nconf);
365 if (unlikely(clist == NULL))
367 module_list_free (mlist);
372 for (size_t i = 0; i < nmod; i++)
374 module_t *parser = mlist[i];
375 module_config_t *item, *end;
377 for (item = parser->p_config, end = item + parser->confsize;
381 if (!CONFIG_ITEM(item->i_type))
382 continue; /* ignore hints */
383 clist[nconf++] = item;
386 module_list_free (mlist);
388 qsort (clist, nconf, sizeof (*clist), confcmp);
391 config.count = nconf;
395 void config_UnsortConfig (void)
397 module_config_t **clist;
406 /*****************************************************************************
407 * config_FindConfig: find the config structure associated with an option.
408 *****************************************************************************
409 * FIXME: remove p_this pointer parameter (or use it)
410 *****************************************************************************/
411 module_config_t *config_FindConfig (vlc_object_t *p_this, const char *name)
415 if (unlikely(name == NULL))
418 module_config_t *const *p;
419 p = bsearch (name, config.list, config.count, sizeof (*p), confnamecmp);
420 return p ? *p : NULL;
424 * Destroys an array of configuration items.
425 * \param config start of array of items
426 * \param confsize number of items in the array
428 void config_Free (module_config_t *config, size_t confsize)
430 for (size_t j = 0; j < confsize; j++)
432 module_config_t *p_item = config + j;
434 free( p_item->psz_type );
435 free( p_item->psz_name );
436 free( p_item->psz_text );
437 free( p_item->psz_longtext );
439 if (IsConfigStringType (p_item->i_type))
441 free (p_item->value.psz);
442 free (p_item->orig.psz);
445 if( p_item->ppsz_list )
446 for (int i = 0; i < p_item->i_list; i++)
447 free( p_item->ppsz_list[i] );
448 if( p_item->ppsz_list_text )
449 for (int i = 0; i < p_item->i_list; i++)
450 free( p_item->ppsz_list_text[i] );
451 free( p_item->ppsz_list );
452 free( p_item->ppsz_list_text );
453 free( p_item->pi_list );
455 if( p_item->i_action )
457 for (int i = 0; i < p_item->i_action; i++)
458 free( p_item->ppsz_action_text[i] );
459 free( p_item->ppf_action );
460 free( p_item->ppsz_action_text );
467 #undef config_ResetAll
468 /*****************************************************************************
469 * config_ResetAll: reset the configuration data for all the modules.
470 *****************************************************************************/
471 void config_ResetAll( vlc_object_t *p_this )
475 module_t **list = module_list_get (NULL);
477 vlc_rwlock_wrlock (&config_lock);
478 for (size_t j = 0; (p_module = list[j]) != NULL; j++)
479 for (size_t i = 0; i < p_module->confsize; i++ )
481 module_config_t *p_config = p_module->p_config + i;
483 if (IsConfigIntegerType (p_config->i_type))
484 p_config->value.i = p_config->orig.i;
486 if (IsConfigFloatType (p_config->i_type))
487 p_config->value.f = p_config->orig.f;
489 if (IsConfigStringType (p_config->i_type))
491 free ((char *)p_config->value.psz);
492 p_config->value.psz =
493 strdupnull (p_config->orig.psz);
496 vlc_rwlock_unlock (&config_lock);
498 module_list_free (list);