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
= xmalloc ((n
+ 2) * sizeof (*vals
));
266 char **txts
= xmalloc ((n
+ 2) * sizeof (*txts
));
268 vals
[0] = xstrdup ("any");
269 txts
[0] = xstrdup (_("Automatic"));
271 for (ssize_t i
= 0; i
< n
; i
++)
273 vals
[i
+ 1] = xstrdup (module_get_object (list
[i
]));
274 txts
[i
+ 1] = xstrdup (module_gettext (list
[i
],
275 module_get_name (list
[i
], true)));
278 vals
[n
+ 1] = xstrdup ("none");
279 txts
[n
+ 1] = xstrdup (_("Disable"));
283 module_list_free (list
);
287 ssize_t
config_GetPszChoices(const char *name
,
288 char ***restrict values
, char ***restrict texts
)
290 *values
= *texts
= NULL
;
292 module_config_t
*cfg
= config_FindConfig(name
);
301 case CONFIG_ITEM_MODULE
:
302 return config_ListModules (cfg
->psz_type
, values
, texts
);
304 if (!IsConfigStringType (cfg
->i_type
))
312 size_t count
= cfg
->list_count
;
315 if (module_Map(NULL
, cfg
->owner
))
321 if (cfg
->list
.psz_cb
== NULL
)
323 return cfg
->list
.psz_cb(name
, values
, texts
);
326 char **vals
= xmalloc (sizeof (*vals
) * count
);
327 char **txts
= xmalloc (sizeof (*txts
) * count
);
329 for (size_t i
= 0; i
< count
; i
++)
331 vals
[i
] = xstrdup ((cfg
->list
.psz
[i
] != NULL
) ? cfg
->list
.psz
[i
] : "");
332 /* FIXME: use module_gettext() instead */
333 txts
[i
] = xstrdup ((cfg
->list_text
[i
] != NULL
)
334 ? vlc_gettext (cfg
->list_text
[i
]) : "");
342 static int confcmp (const void *a
, const void *b
)
344 const module_config_t
*const *ca
= a
, *const *cb
= b
;
346 return strcmp ((*ca
)->psz_name
, (*cb
)->psz_name
);
349 static int confnamecmp (const void *key
, const void *elem
)
351 const module_config_t
*const *conf
= elem
;
353 return strcmp (key
, (*conf
)->psz_name
);
358 module_config_t
**list
;
360 } config
= { NULL
, 0 };
363 * Index the configuration items by name for faster lookups.
365 int config_SortConfig (void)
370 for (p
= vlc_plugins
; p
!= NULL
; p
= p
->next
)
371 nconf
+= p
->conf
.size
;
373 module_config_t
**clist
= vlc_alloc (nconf
, sizeof (*clist
));
374 if (unlikely(clist
== NULL
))
378 for (p
= vlc_plugins
; p
!= NULL
; p
= p
->next
)
380 module_config_t
*item
, *end
;
382 for (item
= p
->conf
.items
, end
= item
+ p
->conf
.size
;
386 if (!CONFIG_ITEM(item
->i_type
))
387 continue; /* ignore hints */
388 clist
[nconf
++] = item
;
392 qsort (clist
, nconf
, sizeof (*clist
), confcmp
);
395 config
.count
= nconf
;
399 void config_UnsortConfig (void)
401 module_config_t
**clist
;
410 module_config_t
*config_FindConfig(const char *name
)
412 if (unlikely(name
== NULL
))
415 module_config_t
*const *p
;
416 p
= bsearch (name
, config
.list
, config
.count
, sizeof (*p
), confnamecmp
);
417 return p
? *p
: NULL
;
421 * Destroys an array of configuration items.
422 * \param config start of array of items
423 * \param confsize number of items in the array
425 void config_Free (module_config_t
*tab
, size_t confsize
)
427 for (size_t j
= 0; j
< confsize
; j
++)
429 module_config_t
*p_item
= &tab
[j
];
431 if (IsConfigStringType (p_item
->i_type
))
433 free (p_item
->value
.psz
);
434 if (p_item
->list_count
)
435 free (p_item
->list
.psz
);
438 free (p_item
->list_text
);
444 void config_ResetAll(void)
446 vlc_rwlock_wrlock (&config_lock
);
447 for (vlc_plugin_t
*p
= vlc_plugins
; p
!= NULL
; p
= p
->next
)
449 for (size_t i
= 0; i
< p
->conf
.size
; i
++ )
451 module_config_t
*p_config
= p
->conf
.items
+ i
;
453 if (IsConfigIntegerType (p_config
->i_type
))
454 p_config
->value
.i
= p_config
->orig
.i
;
456 if (IsConfigFloatType (p_config
->i_type
))
457 p_config
->value
.f
= p_config
->orig
.f
;
459 if (IsConfigStringType (p_config
->i_type
))
461 free ((char *)p_config
->value
.psz
);
462 p_config
->value
.psz
=
463 strdupnull (p_config
->orig
.psz
);
467 vlc_rwlock_unlock (&config_lock
);