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>
29 #include <vlc_actions.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
;
49 int config_GetType(const char *psz_name
)
51 module_config_t
*p_config
= config_FindConfig(psz_name
);
59 switch( CONFIG_CLASS(p_config
->i_type
) )
61 case CONFIG_ITEM_FLOAT
:
63 case CONFIG_ITEM_INTEGER
:
64 return VLC_VAR_INTEGER
;
65 case CONFIG_ITEM_BOOL
:
67 case CONFIG_ITEM_STRING
:
68 return VLC_VAR_STRING
;
74 bool config_IsSafe( const char *name
)
76 module_config_t
*p_config
= config_FindConfig( name
);
77 return p_config
!= NULL
&& p_config
->b_safe
;
80 int64_t config_GetInt(const char *psz_name
)
82 module_config_t
*p_config
= config_FindConfig( psz_name
);
85 assert(p_config
!= NULL
);
86 assert(IsConfigIntegerType(p_config
->i_type
));
90 vlc_rwlock_rdlock (&config_lock
);
91 val
= p_config
->value
.i
;
92 vlc_rwlock_unlock (&config_lock
);
96 float config_GetFloat(const char *psz_name
)
98 module_config_t
*p_config
;
100 p_config
= config_FindConfig( psz_name
);
103 assert(p_config
!= NULL
);
104 assert(IsConfigFloatType(p_config
->i_type
));
108 vlc_rwlock_rdlock (&config_lock
);
109 val
= p_config
->value
.f
;
110 vlc_rwlock_unlock (&config_lock
);
114 char *config_GetPsz(const char *psz_name
)
116 module_config_t
*p_config
;
118 p_config
= config_FindConfig( psz_name
);
121 assert(p_config
!= NULL
);
122 assert(IsConfigStringType (p_config
->i_type
));
124 /* return a copy of the string */
125 vlc_rwlock_rdlock (&config_lock
);
126 char *psz_value
= strdupnull (p_config
->value
.psz
);
127 vlc_rwlock_unlock (&config_lock
);
132 void config_PutPsz(const char *psz_name
, const char *psz_value
)
134 module_config_t
*p_config
= config_FindConfig( psz_name
);
138 assert(p_config
!= NULL
);
139 assert(IsConfigStringType(p_config
->i_type
));
142 if ((psz_value
!= NULL
) && *psz_value
)
143 str
= strdup (psz_value
);
147 vlc_rwlock_wrlock (&config_lock
);
148 oldstr
= (char *)p_config
->value
.psz
;
149 p_config
->value
.psz
= str
;
151 vlc_rwlock_unlock (&config_lock
);
156 void config_PutInt(const char *psz_name
, int64_t i_value
)
158 module_config_t
*p_config
= config_FindConfig( psz_name
);
161 assert(p_config
!= NULL
);
162 assert(IsConfigIntegerType(p_config
->i_type
));
164 if (i_value
< p_config
->min
.i
)
165 i_value
= p_config
->min
.i
;
166 if (i_value
> p_config
->max
.i
)
167 i_value
= p_config
->max
.i
;
169 vlc_rwlock_wrlock (&config_lock
);
170 p_config
->value
.i
= i_value
;
172 vlc_rwlock_unlock (&config_lock
);
175 void config_PutFloat(const char *psz_name
, float f_value
)
177 module_config_t
*p_config
= config_FindConfig( psz_name
);
180 assert(p_config
!= NULL
);
181 assert(IsConfigFloatType(p_config
->i_type
));
183 /* if f_min == f_max == 0, then do not use them */
184 if ((p_config
->min
.f
== 0.f
) && (p_config
->max
.f
== 0.f
))
186 else if (f_value
< p_config
->min
.f
)
187 f_value
= p_config
->min
.f
;
188 else if (f_value
> p_config
->max
.f
)
189 f_value
= p_config
->max
.f
;
191 vlc_rwlock_wrlock (&config_lock
);
192 p_config
->value
.f
= f_value
;
194 vlc_rwlock_unlock (&config_lock
);
197 ssize_t
config_GetIntChoices(const char *name
,
198 int64_t **restrict values
, char ***restrict texts
)
203 module_config_t
*cfg
= config_FindConfig(name
);
206 size_t count
= cfg
->list_count
;
209 if (module_Map(NULL
, cfg
->owner
))
215 if (cfg
->list
.i_cb
== NULL
)
217 return cfg
->list
.i_cb(name
, values
, texts
);
220 int64_t *vals
= vlc_alloc (count
, sizeof (*vals
));
221 char **txts
= vlc_alloc (count
, sizeof (*txts
));
222 if (vals
== NULL
|| txts
== NULL
)
228 for (size_t i
= 0; i
< count
; i
++)
230 vals
[i
] = cfg
->list
.i
[i
];
231 /* FIXME: use module_gettext() instead */
232 txts
[i
] = strdup ((cfg
->list_text
[i
] != NULL
)
233 ? vlc_gettext (cfg
->list_text
[i
]) : "");
234 if (unlikely(txts
[i
] == NULL
))
236 for (int j
= i
- 1; j
>= 0; --j
)
254 static ssize_t
config_ListModules (const char *cap
, char ***restrict values
,
255 char ***restrict texts
)
258 ssize_t n
= module_list_cap (&list
, cap
);
261 *values
= *texts
= NULL
;
265 char **vals
= malloc ((n
+ 2) * sizeof (*vals
));
266 char **txts
= malloc ((n
+ 2) * sizeof (*txts
));
271 *values
= *texts
= NULL
;
277 vals
[i
] = strdup ("any");
278 txts
[i
] = strdup (_("Automatic"));
279 if (!vals
[i
] || !txts
[i
])
285 vals
[i
] = strdup (module_get_object (list
[i
- 1]));
286 txts
[i
] = strdup (module_gettext (list
[i
- 1],
287 module_get_name (list
[i
- 1], true)));
288 if( !vals
[i
] || !txts
[i
])
291 vals
[i
] = strdup ("none");
292 txts
[i
] = strdup (_("Disable"));
293 if( !vals
[i
] || !txts
[i
])
298 module_list_free (list
);
302 for (ssize_t j
= 0; j
<= i
; ++j
)
309 module_list_free (list
);
310 *values
= *texts
= NULL
;
314 ssize_t
config_GetPszChoices(const char *name
,
315 char ***restrict values
, char ***restrict texts
)
317 *values
= *texts
= NULL
;
319 module_config_t
*cfg
= config_FindConfig(name
);
328 case CONFIG_ITEM_MODULE
:
329 return config_ListModules (cfg
->psz_type
, values
, texts
);
331 if (!IsConfigStringType (cfg
->i_type
))
339 size_t count
= cfg
->list_count
;
342 if (module_Map(NULL
, cfg
->owner
))
348 if (cfg
->list
.psz_cb
== NULL
)
350 return cfg
->list
.psz_cb(name
, values
, texts
);
353 char **vals
= malloc (sizeof (*vals
) * count
);
354 char **txts
= malloc (sizeof (*txts
) * count
);
364 for (i
= 0; i
< count
; i
++)
366 vals
[i
] = strdup ((cfg
->list
.psz
[i
] != NULL
) ? cfg
->list
.psz
[i
] : "");
367 /* FIXME: use module_gettext() instead */
368 txts
[i
] = strdup ((cfg
->list_text
[i
] != NULL
)
369 ? vlc_gettext (cfg
->list_text
[i
]) : "");
370 if (!vals
[i
] || !txts
[i
])
379 for (size_t j
= 0; j
<= i
; ++j
)
390 static int confcmp (const void *a
, const void *b
)
392 const module_config_t
*const *ca
= a
, *const *cb
= b
;
394 return strcmp ((*ca
)->psz_name
, (*cb
)->psz_name
);
397 static int confnamecmp (const void *key
, const void *elem
)
399 const module_config_t
*const *conf
= elem
;
401 return strcmp (key
, (*conf
)->psz_name
);
406 module_config_t
**list
;
408 } config
= { NULL
, 0 };
411 * Index the configuration items by name for faster lookups.
413 int config_SortConfig (void)
418 for (p
= vlc_plugins
; p
!= NULL
; p
= p
->next
)
419 nconf
+= p
->conf
.size
;
421 module_config_t
**clist
= vlc_alloc (nconf
, sizeof (*clist
));
422 if (unlikely(clist
== NULL
))
426 for (p
= vlc_plugins
; p
!= NULL
; p
= p
->next
)
428 module_config_t
*item
, *end
;
430 for (item
= p
->conf
.items
, end
= item
+ p
->conf
.size
;
434 if (!CONFIG_ITEM(item
->i_type
))
435 continue; /* ignore hints */
436 clist
[nconf
++] = item
;
440 qsort (clist
, nconf
, sizeof (*clist
), confcmp
);
443 config
.count
= nconf
;
447 void config_UnsortConfig (void)
449 module_config_t
**clist
;
458 module_config_t
*config_FindConfig(const char *name
)
460 if (unlikely(name
== NULL
))
463 module_config_t
*const *p
;
464 p
= bsearch (name
, config
.list
, config
.count
, sizeof (*p
), confnamecmp
);
465 return p
? *p
: NULL
;
469 * Destroys an array of configuration items.
470 * \param config start of array of items
471 * \param confsize number of items in the array
473 void config_Free (module_config_t
*tab
, size_t confsize
)
475 for (size_t j
= 0; j
< confsize
; j
++)
477 module_config_t
*p_item
= &tab
[j
];
479 if (IsConfigStringType (p_item
->i_type
))
481 free (p_item
->value
.psz
);
482 if (p_item
->list_count
)
483 free (p_item
->list
.psz
);
486 free (p_item
->list_text
);
492 void config_ResetAll(void)
494 vlc_rwlock_wrlock (&config_lock
);
495 for (vlc_plugin_t
*p
= vlc_plugins
; p
!= NULL
; p
= p
->next
)
497 for (size_t i
= 0; i
< p
->conf
.size
; i
++ )
499 module_config_t
*p_config
= p
->conf
.items
+ i
;
501 if (IsConfigIntegerType (p_config
->i_type
))
502 p_config
->value
.i
= p_config
->orig
.i
;
504 if (IsConfigFloatType (p_config
->i_type
))
505 p_config
->value
.f
= p_config
->orig
.f
;
507 if (IsConfigStringType (p_config
->i_type
))
509 free ((char *)p_config
->value
.psz
);
510 p_config
->value
.psz
=
511 strdupnull (p_config
->orig
.psz
);
515 vlc_rwlock_unlock (&config_lock
);