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"
38 #include "configuration.h"
39 #include "modules/modules.h"
41 vlc_rwlock_t config_lock
= VLC_STATIC_RWLOCK
;
42 bool config_dirty
= false;
44 static inline char *strdupnull (const char *src
)
46 return src
? strdup (src
) : NULL
;
50 /*****************************************************************************
51 * config_GetType: get the type of a variable (bool, int, float, string)
52 *****************************************************************************
53 * This function is used to get the type of a variable from its name.
54 * Beware, this is quite slow.
55 *****************************************************************************/
56 int config_GetType( vlc_object_t
*p_this
, const char *psz_name
)
58 module_config_t
*p_config
;
61 p_config
= config_FindConfig( p_this
, psz_name
);
69 switch( CONFIG_CLASS(p_config
->i_type
) )
71 case CONFIG_ITEM_FLOAT
:
72 i_type
= VLC_VAR_FLOAT
;
75 case CONFIG_ITEM_INTEGER
:
76 i_type
= VLC_VAR_INTEGER
;
79 case CONFIG_ITEM_BOOL
:
80 i_type
= VLC_VAR_BOOL
;
83 case CONFIG_ITEM_STRING
:
84 i_type
= VLC_VAR_STRING
;
95 bool config_IsSafe( const char *name
)
97 module_config_t
*p_config
= config_FindConfig( NULL
, name
);
98 return p_config
!= NULL
&& p_config
->b_safe
;
102 /*****************************************************************************
103 * config_GetInt: get the value of an int variable
104 *****************************************************************************
105 * This function is used to get the value of variables which are internally
106 * represented by an integer (CONFIG_ITEM_INTEGER and
108 *****************************************************************************/
109 int64_t config_GetInt( vlc_object_t
*p_this
, const char *psz_name
)
111 module_config_t
*p_config
;
113 p_config
= config_FindConfig( p_this
, psz_name
);
118 msg_Err( p_this
, "option %s does not exist", psz_name
);
122 if (!IsConfigIntegerType (p_config
->i_type
))
124 msg_Err( p_this
, "option %s does not refer to an int", psz_name
);
130 vlc_rwlock_rdlock (&config_lock
);
131 val
= p_config
->value
.i
;
132 vlc_rwlock_unlock (&config_lock
);
136 #undef config_GetFloat
137 /*****************************************************************************
138 * config_GetFloat: get the value of a float variable
139 *****************************************************************************
140 * This function is used to get the value of variables which are internally
141 * represented by a float (CONFIG_ITEM_FLOAT).
142 *****************************************************************************/
143 float config_GetFloat( vlc_object_t
*p_this
, const char *psz_name
)
145 module_config_t
*p_config
;
147 p_config
= config_FindConfig( p_this
, psz_name
);
152 msg_Err( p_this
, "option %s does not exist", psz_name
);
156 if (!IsConfigFloatType (p_config
->i_type
))
158 msg_Err( p_this
, "option %s does not refer to a float", psz_name
);
164 vlc_rwlock_rdlock (&config_lock
);
165 val
= p_config
->value
.f
;
166 vlc_rwlock_unlock (&config_lock
);
171 /*****************************************************************************
172 * config_GetPsz: get the string value of a string variable
173 *****************************************************************************
174 * This function is used to get the value of variables which are internally
175 * represented by a string (CONFIG_ITEM_STRING, CONFIG_ITEM_*FILE,
176 * CONFIG_ITEM_DIRECTORY, CONFIG_ITEM_PASSWORD, and CONFIG_ITEM_MODULE).
178 * Important note: remember to free() the returned char* because it's a
179 * duplicate of the actual value. It isn't safe to return a pointer to the
180 * actual value as it can be modified at any time.
181 *****************************************************************************/
182 char * config_GetPsz( vlc_object_t
*p_this
, const char *psz_name
)
184 module_config_t
*p_config
;
186 p_config
= config_FindConfig( p_this
, psz_name
);
191 msg_Err( p_this
, "option %s does not exist", psz_name
);
195 if (!IsConfigStringType (p_config
->i_type
))
197 msg_Err( p_this
, "option %s does not refer to a string", psz_name
);
201 /* return a copy of the string */
202 vlc_rwlock_rdlock (&config_lock
);
203 char *psz_value
= strdupnull (p_config
->value
.psz
);
204 vlc_rwlock_unlock (&config_lock
);
210 /*****************************************************************************
211 * config_PutPsz: set the string value of a string variable
212 *****************************************************************************
213 * This function is used to set the value of variables which are internally
214 * represented by a string (CONFIG_ITEM_STRING, CONFIG_ITEM_*FILE,
215 * CONFIG_ITEM_DIRECTORY, CONFIG_ITEM_PASSWORD, and CONFIG_ITEM_MODULE).
216 *****************************************************************************/
217 void config_PutPsz( vlc_object_t
*p_this
,
218 const char *psz_name
, const char *psz_value
)
220 module_config_t
*p_config
;
222 p_config
= config_FindConfig( p_this
, psz_name
);
228 msg_Warn( p_this
, "option %s does not exist", psz_name
);
232 if (!IsConfigStringType (p_config
->i_type
))
234 msg_Err( p_this
, "option %s does not refer to a string", psz_name
);
239 if ((psz_value
!= NULL
) && *psz_value
)
240 str
= strdup (psz_value
);
244 vlc_rwlock_wrlock (&config_lock
);
245 oldstr
= (char *)p_config
->value
.psz
;
246 p_config
->value
.psz
= str
;
248 vlc_rwlock_unlock (&config_lock
);
254 /*****************************************************************************
255 * config_PutInt: set the integer value of an int variable
256 *****************************************************************************
257 * This function is used to set the value of variables which are internally
258 * represented by an integer (CONFIG_ITEM_INTEGER and
260 *****************************************************************************/
261 void config_PutInt( vlc_object_t
*p_this
, const char *psz_name
,
264 module_config_t
*p_config
;
266 p_config
= config_FindConfig( p_this
, psz_name
);
271 msg_Warn( p_this
, "option %s does not exist", psz_name
);
275 if (!IsConfigIntegerType (p_config
->i_type
))
277 msg_Err( p_this
, "option %s does not refer to an int", psz_name
);
281 if (i_value
< p_config
->min
.i
)
282 i_value
= p_config
->min
.i
;
283 if (i_value
> p_config
->max
.i
)
284 i_value
= p_config
->max
.i
;
286 vlc_rwlock_wrlock (&config_lock
);
287 p_config
->value
.i
= i_value
;
289 vlc_rwlock_unlock (&config_lock
);
292 #undef config_PutFloat
293 /*****************************************************************************
294 * config_PutFloat: set the value of a float variable
295 *****************************************************************************
296 * This function is used to set the value of variables which are internally
297 * represented by a float (CONFIG_ITEM_FLOAT).
298 *****************************************************************************/
299 void config_PutFloat( vlc_object_t
*p_this
,
300 const char *psz_name
, float f_value
)
302 module_config_t
*p_config
;
304 p_config
= config_FindConfig( p_this
, psz_name
);
309 msg_Warn( p_this
, "option %s does not exist", psz_name
);
313 if (!IsConfigFloatType (p_config
->i_type
))
315 msg_Err( p_this
, "option %s does not refer to a float", psz_name
);
319 /* if f_min == f_max == 0, then do not use them */
320 if ((p_config
->min
.f
== 0) && (p_config
->max
.f
== 0))
322 else if (f_value
< p_config
->min
.f
)
323 f_value
= p_config
->min
.f
;
324 else if (f_value
> p_config
->max
.f
)
325 f_value
= p_config
->max
.f
;
327 vlc_rwlock_wrlock (&config_lock
);
328 p_config
->value
.f
= f_value
;
330 vlc_rwlock_unlock (&config_lock
);
334 * Determines a list of suggested values for an integer configuration item.
335 * \param values pointer to a table of integer values [OUT]
336 * \param texts pointer to a table of descriptions strings [OUT]
337 * \return number of choices, or -1 on error
338 * \note the caller is responsible for calling free() on all descriptions and
339 * on both tables. In case of error, both pointers are set to NULL.
341 ssize_t
config_GetIntChoices (vlc_object_t
*obj
, const char *name
,
342 int64_t **restrict values
, char ***restrict texts
)
347 module_config_t
*cfg
= config_FindConfig (obj
, name
);
350 msg_Warn (obj
, "option %s does not exist", name
);
355 size_t count
= cfg
->list_count
;
358 if (cfg
->list
.i_cb
== NULL
)
360 return cfg
->list
.i_cb(obj
, name
, values
, texts
);
363 int64_t *vals
= xmalloc (sizeof (*vals
) * count
);
364 char **txts
= xmalloc (sizeof (*txts
) * count
);
366 for (size_t i
= 0; i
< count
; i
++)
368 vals
[i
] = cfg
->list
.i
[i
];
369 /* FIXME: use module_gettext() instead */
370 txts
[i
] = strdup ((cfg
->list_text
[i
] != NULL
)
371 ? vlc_gettext (cfg
->list_text
[i
]) : "");
372 if (unlikely(txts
[i
] == NULL
))
382 static ssize_t
config_ListModules (const char *cap
, char ***restrict values
,
383 char ***restrict texts
)
386 ssize_t n
= module_list_cap (&list
, cap
);
389 *values
= *texts
= NULL
;
393 char **vals
= xmalloc ((n
+ 2) * sizeof (*vals
));
394 char **txts
= xmalloc ((n
+ 2) * sizeof (*txts
));
396 vals
[0] = xstrdup ("any");
397 txts
[0] = xstrdup (_("Automatic"));
399 for (ssize_t i
= 0; i
< n
; i
++)
401 vals
[i
+ 1] = xstrdup (module_get_object (list
[i
]));
402 txts
[i
+ 1] = xstrdup (module_gettext (list
[i
],
403 module_get_name (list
[i
], true)));
406 vals
[n
+ 1] = xstrdup ("none");
407 txts
[n
+ 1] = xstrdup (_("Disable"));
415 * Determines a list of suggested values for a string configuration item.
416 * \param values pointer to a table of value strings [OUT]
417 * \param texts pointer to a table of descriptions strings [OUT]
418 * \return number of choices, or -1 on error
419 * \note the caller is responsible for calling free() on all values, on all
420 * descriptions and on both tables.
421 * In case of error, both pointers are set to NULL.
423 ssize_t
config_GetPszChoices (vlc_object_t
*obj
, const char *name
,
424 char ***restrict values
, char ***restrict texts
)
426 *values
= *texts
= NULL
;
428 module_config_t
*cfg
= config_FindConfig (obj
, name
);
437 case CONFIG_ITEM_MODULE
:
438 return config_ListModules (cfg
->psz_type
, values
, texts
);
440 if (!IsConfigStringType (cfg
->i_type
))
448 size_t count
= cfg
->list_count
;
451 if (cfg
->list
.psz_cb
== NULL
)
453 return cfg
->list
.psz_cb(obj
, name
, values
, texts
);
456 char **vals
= xmalloc (sizeof (*vals
) * count
);
457 char **txts
= xmalloc (sizeof (*txts
) * count
);
459 for (size_t i
= 0; i
< count
; i
++)
461 vals
[i
] = xstrdup ((cfg
->list
.psz
[i
] != NULL
) ? cfg
->list
.psz
[i
] : "");
462 /* FIXME: use module_gettext() instead */
463 txts
[i
] = xstrdup ((cfg
->list_text
[i
] != NULL
)
464 ? vlc_gettext (cfg
->list_text
[i
]) : "");
472 static int confcmp (const void *a
, const void *b
)
474 const module_config_t
*const *ca
= a
, *const *cb
= b
;
476 return strcmp ((*ca
)->psz_name
, (*cb
)->psz_name
);
479 static int confnamecmp (const void *key
, const void *elem
)
481 const module_config_t
*const *conf
= elem
;
483 return strcmp (key
, (*conf
)->psz_name
);
488 module_config_t
**list
;
490 } config
= { NULL
, 0 };
493 * Index the configuration items by name for faster lookups.
495 int config_SortConfig (void)
497 size_t nmod
, nconf
= 0;
498 module_t
**mlist
= module_list_get (&nmod
);
500 for (size_t i
= 0; i
< nmod
; i
++)
501 nconf
+= mlist
[i
]->confsize
;
503 module_config_t
**clist
= malloc (sizeof (*clist
) * nconf
);
504 if (unlikely(clist
== NULL
))
506 module_list_free (mlist
);
511 for (size_t i
= 0; i
< nmod
; i
++)
513 module_t
*parser
= mlist
[i
];
514 module_config_t
*item
, *end
;
516 for (item
= parser
->p_config
, end
= item
+ parser
->confsize
;
520 if (!CONFIG_ITEM(item
->i_type
))
521 continue; /* ignore hints */
522 clist
[nconf
++] = item
;
525 module_list_free (mlist
);
527 qsort (clist
, nconf
, sizeof (*clist
), confcmp
);
530 config
.count
= nconf
;
534 void config_UnsortConfig (void)
536 module_config_t
**clist
;
545 /*****************************************************************************
546 * config_FindConfig: find the config structure associated with an option.
547 *****************************************************************************
548 * FIXME: remove p_this pointer parameter (or use it)
549 *****************************************************************************/
550 module_config_t
*config_FindConfig (vlc_object_t
*p_this
, const char *name
)
554 if (unlikely(name
== NULL
))
557 module_config_t
*const *p
;
558 p
= bsearch (name
, config
.list
, config
.count
, sizeof (*p
), confnamecmp
);
559 return p
? *p
: NULL
;
563 * Destroys an array of configuration items.
564 * \param config start of array of items
565 * \param confsize number of items in the array
567 void config_Free (module_config_t
*config
, size_t confsize
)
569 for (size_t j
= 0; j
< confsize
; j
++)
571 module_config_t
*p_item
= config
+ j
;
573 free( p_item
->psz_type
);
574 free( p_item
->psz_name
);
575 free( p_item
->psz_text
);
576 free( p_item
->psz_longtext
);
578 if (IsConfigIntegerType (p_item
->i_type
))
580 if (p_item
->list_count
)
581 free (p_item
->list
.i
);
584 if (IsConfigStringType (p_item
->i_type
))
586 free (p_item
->value
.psz
);
587 free (p_item
->orig
.psz
);
588 if (p_item
->list_count
)
590 for (size_t i
= 0; i
< p_item
->list_count
; i
++)
591 free (p_item
->list
.psz
[i
]);
592 free (p_item
->list
.psz
);
596 for (size_t i
= 0; i
< p_item
->list_count
; i
++)
597 free (p_item
->list_text
[i
]);
598 free (p_item
->list_text
);
604 #undef config_ResetAll
605 /*****************************************************************************
606 * config_ResetAll: reset the configuration data for all the modules.
607 *****************************************************************************/
608 void config_ResetAll( vlc_object_t
*p_this
)
611 module_t
**list
= module_list_get (&count
);
613 vlc_rwlock_wrlock (&config_lock
);
614 for (size_t j
= 0; j
< count
; j
++)
616 module_t
*p_module
= list
[j
];
618 for (size_t i
= 0; i
< p_module
->confsize
; i
++ )
620 module_config_t
*p_config
= p_module
->p_config
+ i
;
622 if (IsConfigIntegerType (p_config
->i_type
))
623 p_config
->value
.i
= p_config
->orig
.i
;
625 if (IsConfigFloatType (p_config
->i_type
))
626 p_config
->value
.f
= p_config
->orig
.f
;
628 if (IsConfigStringType (p_config
->i_type
))
630 free ((char *)p_config
->value
.psz
);
631 p_config
->value
.psz
=
632 strdupnull (p_config
->orig
.psz
);
636 vlc_rwlock_unlock (&config_lock
);
638 module_list_free (list
);