1 /*****************************************************************************
2 * core.c management of the modules configuration
3 *****************************************************************************
4 * Copyright (C) 2001-2007 VLC authors and VideoLAN
6 * Authors: Gildas Bazin <gbazin@videolan.org>
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU Lesser General Public License as published by
10 * the Free Software Foundation; either version 2.1 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public License
19 * along with this program; if not, write to the Free Software Foundation,
20 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
21 *****************************************************************************/
27 #include <vlc_common.h>
28 #include <vlc_actions.h>
29 #include <vlc_modules.h>
30 #include <vlc_plugin.h>
32 #include "vlc_configuration.h"
37 #include "configuration.h"
38 #include "modules/modules.h"
40 vlc_rwlock_t config_lock = VLC_STATIC_RWLOCK;
41 bool config_dirty = false;
43 static inline char *strdupnull (const char *src)
45 return src ? strdup (src) : NULL;
48 int config_GetType(const char *psz_name)
50 module_config_t *p_config = config_FindConfig(psz_name);
58 switch( CONFIG_CLASS(p_config->i_type) )
60 case CONFIG_ITEM_FLOAT:
62 case CONFIG_ITEM_INTEGER:
63 return VLC_VAR_INTEGER;
64 case CONFIG_ITEM_BOOL:
66 case CONFIG_ITEM_STRING:
67 return VLC_VAR_STRING;
73 bool config_IsSafe( const char *name )
75 module_config_t *p_config = config_FindConfig( name );
76 return p_config != NULL && p_config->b_safe;
79 static module_config_t * config_FindConfigChecked( const char *psz_name )
81 module_config_t *p_config = config_FindConfig( psz_name );
84 fprintf(stderr, "Unknown vlc configuration variable named %s\n", psz_name);
89 int64_t config_GetInt(const char *psz_name)
91 module_config_t *p_config = config_FindConfigChecked( psz_name );
94 assert(p_config != NULL);
95 assert(IsConfigIntegerType(p_config->i_type));
99 vlc_rwlock_rdlock (&config_lock);
100 val = p_config->value.i;
101 vlc_rwlock_unlock (&config_lock);
105 float config_GetFloat(const char *psz_name)
107 module_config_t *p_config;
109 p_config = config_FindConfigChecked( psz_name );
112 assert(p_config != NULL);
113 assert(IsConfigFloatType(p_config->i_type));
117 vlc_rwlock_rdlock (&config_lock);
118 val = p_config->value.f;
119 vlc_rwlock_unlock (&config_lock);
123 char *config_GetPsz(const char *psz_name)
125 module_config_t *p_config = config_FindConfigChecked( psz_name );
128 assert(p_config != NULL);
129 assert(IsConfigStringType (p_config->i_type));
131 /* return a copy of the string */
132 vlc_rwlock_rdlock (&config_lock);
133 char *psz_value = strdupnull (p_config->value.psz);
134 vlc_rwlock_unlock (&config_lock);
139 void config_PutPsz(const char *psz_name, const char *psz_value)
141 module_config_t *p_config = config_FindConfigChecked( psz_name );
144 assert(p_config != NULL);
145 assert(IsConfigStringType(p_config->i_type));
148 if ((psz_value != NULL) && *psz_value)
149 str = strdup (psz_value);
153 vlc_rwlock_wrlock (&config_lock);
154 oldstr = (char *)p_config->value.psz;
155 p_config->value.psz = str;
157 vlc_rwlock_unlock (&config_lock);
162 void config_PutInt(const char *psz_name, int64_t i_value )
164 module_config_t *p_config = config_FindConfigChecked( psz_name );
167 assert(p_config != NULL);
168 assert(IsConfigIntegerType(p_config->i_type));
170 if (i_value < p_config->min.i)
171 i_value = p_config->min.i;
172 if (i_value > p_config->max.i)
173 i_value = p_config->max.i;
175 vlc_rwlock_wrlock (&config_lock);
176 p_config->value.i = i_value;
178 vlc_rwlock_unlock (&config_lock);
181 void config_PutFloat(const char *psz_name, float f_value)
183 module_config_t *p_config = config_FindConfigChecked( psz_name );
186 assert(p_config != NULL);
187 assert(IsConfigFloatType(p_config->i_type));
189 /* if f_min == f_max == 0, then do not use them */
190 if ((p_config->min.f == 0.f) && (p_config->max.f == 0.f))
192 else if (f_value < p_config->min.f)
193 f_value = p_config->min.f;
194 else if (f_value > p_config->max.f)
195 f_value = p_config->max.f;
197 vlc_rwlock_wrlock (&config_lock);
198 p_config->value.f = f_value;
200 vlc_rwlock_unlock (&config_lock);
203 ssize_t config_GetIntChoices(const char *name,
204 int64_t **restrict values, char ***restrict texts)
209 module_config_t *cfg = config_FindConfigChecked(name);
212 size_t count = cfg->list_count;
215 int (*cb)(const char *, int64_t **, char ***);
217 cb = vlc_plugin_Symbol(NULL, cfg->owner, "vlc_entry_cfg_int_enum");
221 return cb(name, values, texts);
224 int64_t *vals = vlc_alloc (count, sizeof (*vals));
225 char **txts = vlc_alloc (count, sizeof (*txts));
226 if (vals == NULL || txts == NULL)
232 for (size_t i = 0; i < count; i++)
234 vals[i] = cfg->list.i[i];
235 /* FIXME: use module_gettext() instead */
236 txts[i] = strdup ((cfg->list_text[i] != NULL)
237 ? vlc_gettext (cfg->list_text[i]) : "");
238 if (unlikely(txts[i] == NULL))
240 for (int j = i - 1; j >= 0; --j)
258 static ssize_t config_ListModules (const char *cap, char ***restrict values,
259 char ***restrict texts)
261 module_t *const *list;
262 size_t n = module_list_cap(&list, cap);
263 char **vals = malloc ((n + 2) * sizeof (*vals));
264 char **txts = malloc ((n + 2) * sizeof (*txts));
269 *values = *texts = NULL;
275 vals[i] = strdup ("any");
276 txts[i] = strdup (_("Automatic"));
277 if (!vals[i] || !txts[i])
283 vals[i] = strdup (module_get_object (list[i - 1]));
284 txts[i] = strdup (module_gettext (list[i - 1],
285 module_get_name (list[i - 1], true)));
286 if( !vals[i] || !txts[i])
289 vals[i] = strdup ("none");
290 txts[i] = strdup (_("Disable"));
291 if( !vals[i] || !txts[i])
299 for (size_t j = 0; j <= i; ++j)
306 *values = *texts = NULL;
310 ssize_t config_GetPszChoices(const char *name,
311 char ***restrict values, char ***restrict texts)
313 *values = *texts = NULL;
315 module_config_t *cfg = config_FindConfig(name);
324 case CONFIG_ITEM_MODULE:
325 return config_ListModules (cfg->psz_type, values, texts);
327 if (!IsConfigStringType (cfg->i_type))
335 size_t count = cfg->list_count;
338 int (*cb)(const char *, char ***, char ***);
340 cb = vlc_plugin_Symbol(NULL, cfg->owner, "vlc_entry_cfg_str_enum");
344 return cb(name, values, texts);
347 char **vals = malloc (sizeof (*vals) * count);
348 char **txts = malloc (sizeof (*txts) * count);
358 for (i = 0; i < count; i++)
360 vals[i] = strdup ((cfg->list.psz[i] != NULL) ? cfg->list.psz[i] : "");
361 /* FIXME: use module_gettext() instead */
362 txts[i] = strdup ((cfg->list_text[i] != NULL)
363 ? vlc_gettext (cfg->list_text[i]) : "");
364 if (!vals[i] || !txts[i])
373 for (size_t j = 0; j <= i; ++j)
384 static int confcmp (const void *a, const void *b)
386 const module_config_t *const *ca = a, *const *cb = b;
388 return strcmp ((*ca)->psz_name, (*cb)->psz_name);
391 static int confnamecmp (const void *key, const void *elem)
393 const module_config_t *const *conf = elem;
395 return strcmp (key, (*conf)->psz_name);
400 module_config_t **list;
402 } config = { NULL, 0 };
405 * Index the configuration items by name for faster lookups.
407 int config_SortConfig (void)
412 for (p = vlc_plugins; p != NULL; p = p->next)
413 nconf += p->conf.size;
415 module_config_t **clist = vlc_alloc (nconf, sizeof (*clist));
416 if (unlikely(clist == NULL))
420 for (p = vlc_plugins; p != NULL; p = p->next)
422 module_config_t *item, *end;
424 for (item = p->conf.items, end = item + p->conf.size;
428 if (!CONFIG_ITEM(item->i_type))
429 continue; /* ignore hints */
430 clist[nconf++] = item;
434 qsort (clist, nconf, sizeof (*clist), confcmp);
437 config.count = nconf;
441 void config_UnsortConfig (void)
443 module_config_t **clist;
452 module_config_t *config_FindConfig(const char *name)
454 if (unlikely(name == NULL))
457 module_config_t *const *p;
458 p = bsearch (name, config.list, config.count, sizeof (*p), confnamecmp);
459 return p ? *p : NULL;
463 * Destroys an array of configuration items.
464 * \param config start of array of items
465 * \param confsize number of items in the array
467 void config_Free (module_config_t *tab, size_t confsize)
469 for (size_t j = 0; j < confsize; j++)
471 module_config_t *p_item = &tab[j];
473 if (IsConfigStringType (p_item->i_type))
475 free (p_item->value.psz);
476 if (p_item->list_count)
477 free (p_item->list.psz);
480 free (p_item->list_text);
486 void config_ResetAll(void)
488 vlc_rwlock_wrlock (&config_lock);
489 for (vlc_plugin_t *p = vlc_plugins; p != NULL; p = p->next)
491 for (size_t i = 0; i < p->conf.size; i++ )
493 module_config_t *p_config = p->conf.items + i;
495 if (IsConfigIntegerType (p_config->i_type))
496 p_config->value.i = p_config->orig.i;
498 if (IsConfigFloatType (p_config->i_type))
499 p_config->value.f = p_config->orig.f;
501 if (IsConfigStringType (p_config->i_type))
503 free ((char *)p_config->value.psz);
504 p_config->value.psz =
505 strdupnull (p_config->orig.psz);
510 vlc_rwlock_unlock (&config_lock);