1 /* gEDA - GPL Electronic Design Automation
2 * libgeda - gEDA's library - Scheme API
3 * Copyright (C) 2011-2012 Peter Brett <peter@peter-b.co.uk>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA
21 * \file scheme_config.c
22 * \brief Scheme API configuration procedures.
27 #include "libgeda_priv.h"
28 #include "libgedaguile_priv.h"
30 SCM_SYMBOL (system_error_sym
, "system-error");
31 SCM_SYMBOL (config_error_sym
, "config-error");
32 SCM_SYMBOL (unknown_encoding_sym
, "unknown-encoding");
33 SCM_SYMBOL (parse_sym
, "parse");
34 SCM_SYMBOL (key_not_found_sym
, "key-not-found");
35 SCM_SYMBOL (group_not_found_sym
, "group-not-found");
36 SCM_SYMBOL (invalid_value_sym
, "invalid-value");
38 #define ASSERT_CFG_GROUP_KEY(subr) do { \
39 SCM_ASSERT (EDASCM_CONFIGP (cfg_s), cfg_s, SCM_ARG1, subr); \
40 SCM_ASSERT (scm_is_string (group_s), group_s, SCM_ARG2, subr); \
41 SCM_ASSERT (scm_is_string (key_s), key_s, SCM_ARG3, subr); \
44 /*! \brief Convert a GError to a Scheme error.
46 * Raise a Scheme exception for the given \a error, with the procedure
47 * name \a subr. The \a error will be freed with g_clear_error(). Does
50 * The \a error will be converted to a Scheme error according to the
53 * - If \a error is a GFileError, it will be converted to a
56 * - If \a error is an EdaConfigError, it will be converted to a
59 * - Otherwise, it will be converted to a misc-error.
61 * \bug For GFileErrors, the GLib error code will be returned rather
62 * than the system error code.
64 * \param subr name of failed procedure, or NULL.
65 * \param error error to be converted to a Scheme exception.
68 error_from_gerror (const gchar
*subr
, GError
**error
)
70 if (error
== NULL
|| *error
== NULL
) {
71 scm_misc_error (subr
, "Unknown error", SCM_EOL
);
76 scm_dynwind_begin (0);
77 /* Make sure that the GError gets cleaned up when the non-local exit
79 scm_dynwind_unwind_handler ((void (*)(void *)) g_clear_error
, error
,
80 SCM_F_WIND_EXPLICITLY
);
84 if (err
->domain
== G_IO_ERROR
) {
85 /* File-related errors */
86 scm_error (system_error_sym
, subr
, err
->message
, SCM_EOL
,
87 scm_list_1 (scm_from_int (err
->code
)));
90 if (err
->domain
== EDA_CONFIG_ERROR
) {
91 /* Configuration context-related errors */
93 case EDA_CONFIG_ERROR_UNKNOWN_ENCODING
:
94 rest
= scm_list_1 (unknown_encoding_sym
);
96 case EDA_CONFIG_ERROR_PARSE
:
97 rest
= scm_list_1 (parse_sym
);
99 case EDA_CONFIG_ERROR_KEY_NOT_FOUND
:
100 rest
= scm_list_1 (key_not_found_sym
);
102 case EDA_CONFIG_ERROR_GROUP_NOT_FOUND
:
103 rest
= scm_list_1 (group_not_found_sym
);
105 case EDA_CONFIG_ERROR_INVALID_VALUE
:
106 rest
= scm_list_1 (invalid_value_sym
);
112 scm_error (config_error_sym
, subr
, err
->message
, SCM_EOL
, rest
);
115 /* All other errors */
116 scm_misc_error (subr
, err
->message
, SCM_EOL
);
119 g_warn_if_reached ();
122 /*! \brief Get the default configuration context.
123 * \par Function Description
124 * Returns the configuration context for compiled-in default settings.
126 * \see eda_config_get_default_context().
128 * \note Scheme API: Implements the \%default-config-context procedure
129 * in the (geda core config) module.
131 * \return an #EdaConfig smob for the default context.
133 SCM_DEFINE (default_config_context
, "%default-config-context", 0, 0, 0,
134 (), "Get default configuration context.")
136 return edascm_from_config (eda_config_get_default_context ());
139 /*! \brief Get the system configuration context.
140 * \par Function Description
141 * Returns the configuration context for system settings.
143 * \see eda_config_get_system_context().
145 * \note Scheme API: Implements the \%system-config-context procedure
146 * in the (geda core config) module.
148 * \return an #EdaConfig smob for the system context.
150 SCM_DEFINE (system_config_context
, "%system-config-context", 0, 0, 0,
151 (), "Get system configuration context.")
153 return edascm_from_config (eda_config_get_system_context ());
156 /*! \brief Get the user configuration context.
157 * \par Function Description
158 * Returns the configuration context for user settings.
160 * \see eda_config_get_user_context().
162 * \note Scheme API: Implements the \%user-config-context procedure
163 * in the (geda core config) module.
165 * \return an #EdaConfig smob for the user context.
167 SCM_DEFINE (user_config_context
, "%user-config-context", 0, 0, 0,
168 (), "Get user configuration context.")
170 return edascm_from_config (eda_config_get_user_context ());
173 /*! \brief Get the configuration context for a path.
174 * \par Function Description
175 * Looks for a configuration file named "geda.conf" in \a path or a
178 * \see eda_config_get_context_for_path().
180 * \note Scheme API: Implements the \%path-config-context procedure in
181 * the (geda core config) module.
183 * \param [in] path_s Path to get context for, as a string.
184 * \return an #EdaConfig smob for \a path.
186 SCM_DEFINE (path_config_context
, "%path-config-context", 1, 0, 0,
187 (SCM path_s
), "Get configuration context for a path.")
189 SCM_ASSERT (scm_is_string (path_s
), path_s
, SCM_ARG1
,
190 s_path_config_context
);
192 scm_dynwind_begin (0);
193 char *path
= scm_to_utf8_string (path_s
);
194 scm_dynwind_free (path
);
195 GFile
*file
= g_file_parse_name (path
);
196 scm_dynwind_unwind_handler (g_object_unref
, file
,
197 SCM_F_WIND_EXPLICITLY
);
199 EdaConfig
*cfg
= eda_config_get_context_for_file (file
);
200 SCM result
= edascm_from_config (cfg
);
203 scm_remember_upto_here_1 (path_s
);
207 /*! \brief Get a configuration context's filename.
208 * \par Function Description
209 * Returns the underlying filename for the configuration context \a
210 * cfg, or #f if it has no filename associated with it.
212 * \see eda_config_get_file().
214 * \note Scheme API: Implements the \%config-filename procedure in the
215 * (geda core config) module.
217 * \param cfg_s #EdaConfig smob for configuration context.
218 * \return string containing configuration filename.
220 SCM_DEFINE (config_filename
, "%config-filename", 1, 0, 0,
221 (SCM cfg_s
), "Get configuration filename.")
223 SCM_ASSERT (EDASCM_CONFIGP (cfg_s
), cfg_s
, SCM_ARG1
,
226 scm_dynwind_begin (0);
227 EdaConfig
*cfg
= edascm_to_config (cfg_s
);
228 GFile
*file
= eda_config_get_file (cfg
);
231 path
= g_file_get_parse_name (file
);
232 scm_dynwind_free (path
);
235 SCM result
= (path
== NULL
) ? SCM_BOOL_F
: scm_from_utf8_string (path
);
240 /*! \brief Load configuration parameters from file.
241 * \par Function Description
242 * Attempt to load configuration parameters for \a cfg_s from file.
243 * Raises a system-error on failure.
245 * \see eda_config_load().
247 * \note Scheme API: Implements the \%config-load! procedure in the
248 * (geda core config) module.
250 * \param cfg_s #EdaConfig smob for configuration context to load.
253 SCM_DEFINE (config_load_x
, "%config-load!", 1, 0, 0,
254 (SCM cfg_s
), "Load configuration parameters from file.")
256 SCM_ASSERT (EDASCM_CONFIGP (cfg_s
), cfg_s
, SCM_ARG1
,
259 EdaConfig
*cfg
= edascm_to_config (cfg_s
);
260 GError
*error
= NULL
;
261 if (!eda_config_load (cfg
, &error
)) {
262 error_from_gerror (s_config_load_x
, &error
);
267 /*! \brief Test if configuration context has been loaded.
268 * \par Function Description
269 * Returns #t if \a cfg_s has been loaded from file at some point, and
272 * \see eda_config_is_loaded().
274 * \note Scheme API: Implements the \%config-loaded? procedure in the
275 * (geda core config) module.
277 * \param cfg_s #EdaConfig smob of configuration context.
278 * \return #t if \a cfg_s has been loaded; #f otherwise.
280 SCM_DEFINE (config_loaded_p
, "%config-loaded?", 1, 0, 0,
281 (SCM cfg_s
), "Test if configuration context has been loaded")
283 SCM_ASSERT (EDASCM_CONFIGP (cfg_s
), cfg_s
, SCM_ARG1
,
286 EdaConfig
*cfg
= edascm_to_config (cfg_s
);
287 return eda_config_is_loaded (cfg
) ? SCM_BOOL_T
: SCM_BOOL_F
;
290 /*! \brief Save changes to a configuration context.
291 * \par Function Description
292 * Attempt to save configuration parameters for the context \a cfg_s
293 * to its ssociated file. Raises a system-error on failure.
295 * \see eda_config_save().
297 * \note Scheme API: Implements the \%config-save! procedure in the
298 * (geda core config) module.
300 * \param cfg_s #EdaConfig smob of configuration context.
303 SCM_DEFINE (config_save_x
, "%config-save!", 1, 0, 0,
304 (SCM cfg_s
), "Save changes to a configuration context")
306 SCM_ASSERT (EDASCM_CONFIGP (cfg_s
), cfg_s
, SCM_ARG1
,
309 EdaConfig
*cfg
= edascm_to_config (cfg_s
);
310 GError
*error
= NULL
;
311 if (!eda_config_save (cfg
, &error
)) {
312 error_from_gerror (s_config_load_x
, &error
);
317 /*! \brief Test whether a configuration context was changed since last save/load.
318 * \par Function Description
319 * Determine whether the configuration context \a cfg has been altered
320 * since it was last synchronised with the on-disk version by loading
323 * \see eda_config_is_changed().
325 * \note Scheme API: Implements the \%config-changed? procedure in the
326 * (geda core config) module.
328 * \param cfg_s #EdaConfig smob of configuration context.
329 * \return #t if \a cfg_s has unsaved changes, #f otherwise.
331 SCM_DEFINE (config_changed_p
, "%config-changed?", 1, 0, 0,
333 "Test whether a configuration context was changed since last save/load.")
335 SCM_ASSERT (EDASCM_CONFIGP (cfg_s
), cfg_s
, SCM_ARG1
,
338 EdaConfig
*cfg
= edascm_to_config (cfg_s
);
339 return eda_config_is_changed (cfg
) ? SCM_BOOL_T
: SCM_BOOL_F
;
342 /*! \brief Get a configuration context's parent context.
343 * \par Function Description
344 * Return the parent context of the configuration context \a cfg, if
345 * it has one, or #f otherwise.
347 * \see eda_config_get_parent().
349 * \note Scheme API: Implements the \%config-parent procedure in the
350 * (geda core config) module.
352 * \param cfg_s #EdaConfig smob of configuration context.
353 * \return parent context of \a cfg_s, or #f.
355 SCM_DEFINE (config_parent
, "%config-parent", 1, 0, 0,
356 (SCM cfg_s
), "Get a configuration context's parent context.")
358 SCM_ASSERT (EDASCM_CONFIGP (cfg_s
), cfg_s
, SCM_ARG1
,
361 EdaConfig
*cfg
= edascm_to_config (cfg_s
);
362 EdaConfig
*parent
= eda_config_get_parent (cfg
);
363 return (parent
== NULL
) ? SCM_BOOL_F
: edascm_from_config (parent
);
366 /*! \brief Set a configuration context's parent context.
367 * \par Function Description
368 * Set the parent context of the configuration context \a cfg to \a
369 * parent. If \a parent is #f, sets \a cfg as having no parent
372 * \see eda_config_set_parent().
374 * \note Scheme API: Implements the \%set-config-parent! procedure in
375 * the (geda core config) module.
377 * \param cfg_s #EdaConfig smob of configuration context.
378 * \param parent_s #EdaConfig smob of new parent context, or #f.
381 SCM_DEFINE (set_config_parent_x
, "%set-config-parent!", 2, 0, 0,
382 (SCM cfg_s
, SCM parent_s
), "Set a configuration context's parent context.")
384 SCM_ASSERT (EDASCM_CONFIGP (cfg_s
), cfg_s
, SCM_ARG1
,
385 s_set_config_parent_x
);
386 SCM_ASSERT (scm_is_false (parent_s
) || EDASCM_CONFIGP (parent_s
), cfg_s
,
387 SCM_ARG2
, s_set_config_parent_x
);
389 EdaConfig
*cfg
= edascm_to_config (cfg_s
);
390 EdaConfig
*parent
= EDASCM_CONFIGP (parent_s
) ? edascm_to_config (parent_s
) : NULL
;
391 eda_config_set_parent (cfg
, parent
);
395 /*! \brief Test if a configuration context is trusted.
396 * \par Function Description
397 * Tests if \a cfg_s is a "trusted" configuration context
398 * (i.e. if it is permitted as a source for risky configuration
399 * parameters such as system commands).
401 * \see eda_config_is_trusted().
403 * \note Scheme API: Implements the \%config-trusted? procedure in
404 * the (geda core config) module.
406 * \param cfg_s #EdaConfig smob of configuration context.
407 * \return #t if \a cfg_s is trusted, #f otherwise.
409 SCM_DEFINE (config_trusted_p
, "%config-trusted?", 1, 0, 0,
410 (SCM cfg_s
), "Test if a configuration context is trusted.")
412 SCM_ASSERT (EDASCM_CONFIGP (cfg_s
), cfg_s
, SCM_ARG1
,
414 EdaConfig
*cfg
= edascm_to_config (cfg_s
);
415 return eda_config_is_trusted (cfg
) ? SCM_BOOL_T
: SCM_BOOL_F
;
418 /*! \brief Set whether a configuration context is trusted.
419 * \par Function Description
420 * Set whether the configuration context \a cfg_s is trusted as a
421 * source for risky configuration parameters.
423 * \see eda_config_set_trusted().
425 * \note Scheme API: Implements the \%set-config-trusted! procedure in
426 * the (geda core config) module.
428 * \param cfg_s #EdaConfig smob of configuration context.
429 * \param trusted_s #f if \a cfg_s is not to be trusted.
432 SCM_DEFINE (set_config_trusted_x
, "%set-config-trusted!", 2, 0, 0,
433 (SCM cfg_s
, SCM trusted_s
),
434 "Set whether configuration context is trusted.")
436 SCM_ASSERT (EDASCM_CONFIGP (cfg_s
), cfg_s
, SCM_ARG1
,
437 s_set_config_trusted_x
);
439 EdaConfig
*cfg
= edascm_to_config (cfg_s
);
440 eda_config_set_trusted (cfg
, scm_is_true (trusted_s
));
444 /*! \brief Get a list of available configuration groups.
445 * \par Function Description.
446 * Returns a list of the all groups available in \a cfg_s and its parent
449 * \see eda_config_get_groups().
451 * \note Scheme API: Implements the \%config-groups procedure in
452 * the (geda core config) module.
454 * \param cfg_s #EdaConfig smob of configuration context.
455 * \return a list of available group names as strings.
457 SCM_DEFINE (config_groups
, "%config-groups", 1, 0, 0,
459 "Get a list of available configuration groups.")
461 SCM_ASSERT (EDASCM_CONFIGP (cfg_s
), cfg_s
, SCM_ARG1
,
464 EdaConfig
*cfg
= edascm_to_config (cfg_s
);
466 gchar
**groups
= eda_config_get_groups (cfg
, &len
);
469 scm_dynwind_begin (0);
470 scm_dynwind_unwind_handler ((void (*)(void *)) g_strfreev
,
471 groups
, SCM_F_WIND_EXPLICITLY
);
473 for (i
= 0; i
< len
; i
++) {
474 lst_s
= scm_cons (scm_from_utf8_string (groups
[i
]), lst_s
);
479 return scm_reverse_x (lst_s
, SCM_EOL
);
482 /*! \brief Test whether a configuration context has a particular group.
483 * \par Function Description
484 * Tests whether the configuration context \a cfg_s, or any of its
485 * parent contexts, contains the \a group_s.
487 * \see eda_config_has_group().
489 * \note Scheme API: Implements the \%config-has-group? procedure in
490 * the (geda core config) module.
492 * \param cfg_s #EdaConfig smob of configuration context.
493 * \param group_s Group name as a string.
494 * \return #t if \a cfg_s or any ancestor contains \a group, #f
497 SCM_DEFINE (config_has_group_p
, "%config-has-group?", 2, 0, 0,
498 (SCM cfg_s
, SCM group_s
),
499 "Test whether a configuration context has a particular group.")
501 SCM_ASSERT (EDASCM_CONFIGP (cfg_s
), cfg_s
, SCM_ARG1
,
502 s_config_has_group_p
);
503 SCM_ASSERT (scm_is_string (group_s
), group_s
, SCM_ARG2
,
504 s_config_has_group_p
);
506 EdaConfig
*cfg
= edascm_to_config (cfg_s
);
507 char *group
= scm_to_utf8_string (group_s
);
508 gboolean result
= eda_config_has_group (cfg
, group
);
510 return result
? SCM_BOOL_T
: SCM_BOOL_F
;
513 /*! \brief Get a list of available configuration keys.
514 * \par Function Description.
515 * Returns a list of the all keys available in \a cfg_s and \a
516 * group_s. If the \a group_s cannot be found, raises a
519 * \see eda_config_get_keys().
521 * \note Scheme API: Implements the \%config-keys procedure in
522 * the (geda core config) module.
524 * \param cfg_s #EdaConfig smob of configuration context.
525 * \param group_s Group name as a string.
526 * \return a list of available key names as strings.
528 SCM_DEFINE (config_keys
, "%config-keys", 2, 0, 0,
529 (SCM cfg_s
, SCM group_s
),
530 "Get a list of available configuration keys.")
532 SCM_ASSERT (EDASCM_CONFIGP (cfg_s
), cfg_s
, SCM_ARG1
,
534 SCM_ASSERT (scm_is_string (group_s
), group_s
, SCM_ARG2
,
537 EdaConfig
*cfg
= edascm_to_config (cfg_s
);
538 char *group
= scm_to_utf8_string (group_s
);
540 GError
*error
= NULL
;
541 gchar
**keys
= eda_config_get_keys (cfg
, group
, &len
, &error
);
545 if (keys
== NULL
) error_from_gerror (s_config_keys
, &error
);
547 scm_dynwind_begin (0);
548 scm_dynwind_unwind_handler ((void (*)(void *)) g_strfreev
,
549 keys
, SCM_F_WIND_EXPLICITLY
);
551 for (i
= 0; i
< len
; i
++) {
552 lst_s
= scm_cons (scm_from_utf8_string (keys
[i
]), lst_s
);
557 return scm_reverse_x (lst_s
, SCM_EOL
);
560 /*! \brief Get the originating context for a configuration parameter.
561 * \par Function Description
562 * Returns the configuration context (either \a cfg_s or one of its
563 * parent contexts) in which the configuration parameter with the
564 * given \a group_s and \a key_s has a value specified. If the group
565 * or key cannot be found, raises a 'config-error'.
567 * \see eda_config_get_source().
569 * \note Scheme API: Implements the \%config-source procedure in the
570 * (geda core config module).
572 * \param cfg_s #EdaConfig smob of configuration context.
573 * \param group_s Group name as a string.
574 * \param key_s Key name as a string.
575 * \return #EdaConfig smob of originating context of parameter.
577 SCM_DEFINE (config_source
, "%config-source", 3, 0, 0,
578 (SCM cfg_s
, SCM group_s
, SCM key_s
),
579 "Get the originating context for a configuration parameter")
581 ASSERT_CFG_GROUP_KEY (s_config_source
);
583 scm_dynwind_begin (0);
584 EdaConfig
*cfg
= edascm_to_config (cfg_s
);
585 char *group
= scm_to_utf8_string (group_s
);
586 scm_dynwind_free (group
);
587 char *key
= scm_to_utf8_string (key_s
);
588 scm_dynwind_free (key
);
589 GError
*error
= NULL
;
590 EdaConfig
*src
= eda_config_get_source (cfg
, group
, key
, &error
);
591 if (src
== NULL
) error_from_gerror (s_config_source
, &error
);
593 return edascm_from_config (src
);
596 /*! \brief Get a configuration parameter's value as a string.
597 * \par Function Description
598 * Get the value of the configuration parameter specified by \a
599 * group_s and \a key_s in the configuration context \a cfg_s, as a
602 * \see eda_config_get_string().
604 * \note Scheme API: Implements the \%config-string procedure in the
605 * (geda core config) module.
607 * \param cfg_s #EdaConfig smob of configuration context.
608 * \param group_s Group name as a string.
609 * \param key_s Key name as a string.
610 * \return configuration value as a string.
612 SCM_DEFINE (config_string
, "%config-string", 3, 0, 0,
613 (SCM cfg_s
, SCM group_s
, SCM key_s
),
614 "Get a configuration parameter's value as a string.")
616 ASSERT_CFG_GROUP_KEY (s_config_string
);
618 scm_dynwind_begin (0);
619 EdaConfig
*cfg
= edascm_to_config (cfg_s
);
620 char *group
= scm_to_utf8_string (group_s
);
621 scm_dynwind_free (group
);
622 char *key
= scm_to_utf8_string (key_s
);
623 scm_dynwind_free (key
);
624 GError
*error
= NULL
;
625 gchar
*value
= eda_config_get_string (cfg
, group
, key
, &error
);
626 if (value
== NULL
) error_from_gerror (s_config_string
, &error
);
627 scm_dynwind_unwind_handler ((void (*)(void *)) g_free
, value
,
628 SCM_F_WIND_EXPLICITLY
);
629 SCM value_s
= scm_from_utf8_string (value
);
634 /*! \brief Get a configuration parameter's value as a boolean.
635 * \par Function Description
636 * Get the value of the configuration parameter specified by \a
637 * group_s and \a key_s in the configuration context \a cfg_s, as a
640 * \see eda_config_get_boolean().
642 * \note Scheme API: Implements the \%config-boolean procedure in the
643 * (geda core config) module.
645 * \param cfg_s #EdaConfig smob of configuration context.
646 * \param group_s Group name as a string.
647 * \param key_s Key name as a string.
648 * \return configuration value as a boolean.
650 SCM_DEFINE (config_boolean
, "%config-boolean", 3, 0, 0,
651 (SCM cfg_s
, SCM group_s
, SCM key_s
),
652 "Get a configuration parameter's value as a boolean.")
654 ASSERT_CFG_GROUP_KEY (s_config_boolean
);
656 scm_dynwind_begin (0);
657 EdaConfig
*cfg
= edascm_to_config (cfg_s
);
658 char *group
= scm_to_utf8_string (group_s
);
659 scm_dynwind_free (group
);
660 char *key
= scm_to_utf8_string (key_s
);
661 scm_dynwind_free (key
);
662 GError
*error
= NULL
;
663 gboolean value
= eda_config_get_boolean (cfg
, group
, key
, &error
);
664 if (error
!= NULL
) error_from_gerror (s_config_boolean
, &error
);
666 return value
? SCM_BOOL_T
: SCM_BOOL_F
;
669 /*! \brief Get a configuration parameter's value as an integer.
670 * \par Function Description
671 * Get the value of the configuration parameter specified by \a
672 * group_s and \a key_s in the configuration context \a cfg_s, as a
675 * \see eda_config_get_int().
677 * \note Scheme API: Implements the \%config-int procedure in the
678 * (geda core config) module.
680 * \param cfg_s #EdaConfig smob of configuration context.
681 * \param group_s Group name as a string.
682 * \param key_s Key name as a string.
683 * \return configuration value as an integer.
685 SCM_DEFINE (config_int
, "%config-int", 3, 0, 0,
686 (SCM cfg_s
, SCM group_s
, SCM key_s
),
687 "Get a configuration parameter's value as an integer.")
689 ASSERT_CFG_GROUP_KEY (s_config_int
);
691 scm_dynwind_begin (0);
692 EdaConfig
*cfg
= edascm_to_config (cfg_s
);
693 char *group
= scm_to_utf8_string (group_s
);
694 scm_dynwind_free (group
);
695 char *key
= scm_to_utf8_string (key_s
);
696 scm_dynwind_free (key
);
697 GError
*error
= NULL
;
698 gint value
= eda_config_get_int (cfg
, group
, key
, &error
);
699 if (error
!= NULL
) error_from_gerror (s_config_int
, &error
);
701 return scm_from_int (value
);
704 /*! \brief Get a configuration parameter's value as a real.
705 * \par Function Description
706 * Get the value of the configuration parameter specified by \a
707 * group_s and \a key_s in the configuration context \a cfg_s, as an
708 * inexact real number.
710 * \see eda_config_get_double().
712 * \note Scheme API: Implements the \%config-real procedure in the
713 * (geda core config) module.
715 * \param cfg_s #EdaConfig smob of configuration context.
716 * \param group_s Group name as a string.
717 * \param key_s Key name as a string.
718 * \return configuration value as an inexact real.
720 SCM_DEFINE (config_real
, "%config-real", 3, 0, 0,
721 (SCM cfg_s
, SCM group_s
, SCM key_s
),
722 "Get a configuration parameter's value as a real.")
724 ASSERT_CFG_GROUP_KEY (s_config_real
);
726 scm_dynwind_begin (0);
727 EdaConfig
*cfg
= edascm_to_config (cfg_s
);
728 char *group
= scm_to_utf8_string (group_s
);
729 scm_dynwind_free (group
);
730 char *key
= scm_to_utf8_string (key_s
);
731 scm_dynwind_free (key
);
732 GError
*error
= NULL
;
733 gdouble value
= eda_config_get_double (cfg
, group
, key
, &error
);
734 if (error
!= NULL
) error_from_gerror (s_config_real
, &error
);
736 return scm_from_double (value
);
739 /*! \brief Get a configuration parameter's value as a string list.
740 * \par Function Description
741 * Get the value of the configuration parameter specified by \a
742 * group_s and \a key_s in the configuration context \a cfg_s, as a
745 * \see eda_config_get_string_list().
747 * \note Scheme API: Implements the \%config-string-list procedure in
748 * the (geda core config) module.
750 * \param cfg_s #EdaConfig smob of configuration context.
751 * \param group_s Group name as a string.
752 * \param key_s Key name as a string.
753 * \return configuration value as a list of strings.
755 SCM_DEFINE (config_string_list
, "%config-string-list", 3, 0, 0,
756 (SCM cfg_s
, SCM group_s
, SCM key_s
),
757 "Get a configuration parameter's value as a string list.")
759 ASSERT_CFG_GROUP_KEY (s_config_string_list
);
761 scm_dynwind_begin (0);
762 EdaConfig
*cfg
= edascm_to_config (cfg_s
);
763 char *group
= scm_to_utf8_string (group_s
);
764 scm_dynwind_free (group
);
765 char *key
= scm_to_utf8_string (key_s
);
766 scm_dynwind_free (key
);
768 GError
*error
= NULL
;
769 gchar
**value
= eda_config_get_string_list (cfg
, group
, key
,
771 if (value
== NULL
) error_from_gerror (s_config_string_list
, &error
);
772 scm_dynwind_unwind_handler ((void (*)(void *)) g_strfreev
, value
,
773 SCM_F_WIND_EXPLICITLY
);
774 SCM value_s
= SCM_EOL
;
775 for (i
= 0; i
< length
; i
++) {
776 value_s
= scm_cons (scm_from_utf8_string (value
[i
]), value_s
);
779 return scm_reverse_x (value_s
, SCM_EOL
);
782 /*! \brief Get a configuration parameter's value as a boolean list.
783 * \par Function Description
784 * Get the value of the configuration parameter specified by \a
785 * group_s and \a key_s in the configuration context \a cfg_s, as a
788 * \see eda_config_get_boolean_list().
790 * \note Scheme API: Implements the \%config-boolean-list procedure in
791 * the (geda core config) module.
793 * \param cfg_s #EdaConfig smob of configuration context.
794 * \param group_s Group name as a string.
795 * \param key_s Key name as a string.
796 * \return configuration value as a list of booleans.
798 SCM_DEFINE (config_boolean_list
, "%config-boolean-list", 3, 0, 0,
799 (SCM cfg_s
, SCM group_s
, SCM key_s
),
800 "Get a configuration parameter's value as a boolean list.")
802 ASSERT_CFG_GROUP_KEY (s_config_boolean_list
);
804 scm_dynwind_begin (0);
805 EdaConfig
*cfg
= edascm_to_config (cfg_s
);
806 char *group
= scm_to_utf8_string (group_s
);
807 scm_dynwind_free (group
);
808 char *key
= scm_to_utf8_string (key_s
);
809 scm_dynwind_free (key
);
811 GError
*error
= NULL
;
812 gboolean
*value
= eda_config_get_boolean_list (cfg
, group
, key
,
814 if (value
== NULL
) error_from_gerror (s_config_boolean_list
, &error
);
815 scm_dynwind_unwind_handler (g_free
, value
,
816 SCM_F_WIND_EXPLICITLY
);
817 SCM value_s
= SCM_EOL
;
818 for (i
= 0; i
< length
; i
++) {
819 value_s
= scm_cons (value
[i
] ? SCM_BOOL_T
: SCM_BOOL_F
, value_s
);
822 return scm_reverse_x (value_s
, SCM_EOL
);
825 /*! \brief Get a configuration parameter's value as an integer list.
826 * \par Function Description
827 * Get the value of the configuration parameter specified by \a
828 * group_s and \a key_s in the configuration context \a cfg_s, as a
831 * \see eda_config_get_int_list().
833 * \note Scheme API: Implements the \%config-int-list procedure in
834 * the (geda core config) module.
836 * \param cfg_s #EdaConfig smob of configuration context.
837 * \param group_s Group name as a string.
838 * \param key_s Key name as a string.
839 * \return configuration value as a list of integers.
841 SCM_DEFINE (config_int_list
, "%config-int-list", 3, 0, 0,
842 (SCM cfg_s
, SCM group_s
, SCM key_s
),
843 "Get a configuration parameter's value as an integer list.")
845 ASSERT_CFG_GROUP_KEY (s_config_int_list
);
847 scm_dynwind_begin (0);
848 EdaConfig
*cfg
= edascm_to_config (cfg_s
);
849 char *group
= scm_to_utf8_string (group_s
);
850 scm_dynwind_free (group
);
851 char *key
= scm_to_utf8_string (key_s
);
852 scm_dynwind_free (key
);
854 GError
*error
= NULL
;
855 gint
*value
= eda_config_get_int_list (cfg
, group
, key
,
857 if (value
== NULL
) error_from_gerror (s_config_int_list
, &error
);
858 scm_dynwind_unwind_handler (g_free
, value
,
859 SCM_F_WIND_EXPLICITLY
);
860 SCM value_s
= SCM_EOL
;
861 for (i
= 0; i
< length
; i
++) {
862 value_s
= scm_cons (scm_from_int (value
[i
]), value_s
);
865 return scm_reverse_x (value_s
, SCM_EOL
);
868 /*! \brief Get a configuration parameter's value as a list of reals.
869 * \par Function Description
870 * Get the value of the configuration parameter specified by \a
871 * group_s and \a key_s in the configuration context \a cfg_s, as a
872 * list of inexact real numbers.
874 * \see eda_config_get_double_list().
876 * \note Scheme API: Implements the \%config-real-list procedure in
877 * the (geda core config) module.
879 * \param cfg_s #EdaConfig smob of configuration context.
880 * \param group_s Group name as a string.
881 * \param key_s Key name as a string.
882 * \return configuration value as a list of inexact real numbers.
884 SCM_DEFINE (config_real_list
, "%config-real-list", 3, 0, 0,
885 (SCM cfg_s
, SCM group_s
, SCM key_s
),
886 "Get a configuration parameter's value as a list of reals.")
888 ASSERT_CFG_GROUP_KEY (s_config_real_list
);
890 scm_dynwind_begin (0);
891 EdaConfig
*cfg
= edascm_to_config (cfg_s
);
892 char *group
= scm_to_utf8_string (group_s
);
893 scm_dynwind_free (group
);
894 char *key
= scm_to_utf8_string (key_s
);
895 scm_dynwind_free (key
);
897 GError
*error
= NULL
;
898 gdouble
*value
= eda_config_get_double_list (cfg
, group
, key
,
900 if (value
== NULL
) error_from_gerror (s_config_real_list
, &error
);
901 scm_dynwind_unwind_handler (g_free
, value
,
902 SCM_F_WIND_EXPLICITLY
);
903 SCM value_s
= SCM_EOL
;
904 for (i
= 0; i
< length
; i
++) {
905 value_s
= scm_cons (scm_from_double (value
[i
]), value_s
);
908 return scm_reverse_x (value_s
, SCM_EOL
);
911 /*! \brief Set a configuration parameter's value.
912 * \par Function Description
913 * Set the value of the configuration parameter specified by \a
914 * group_s and \a key_s in the configuration context \a cfg_s to \a
915 * value_s. The supported types for \a value_s are strings, integers,
916 * real numbers, and booleans, along with homogenous lists of strings,
917 * integers, real numbers or booleans.
919 * \note Scheme API: Implements the \%set-config! procedure in the
920 * (geda core config) module.
922 * \param cfg_s #EdaConfig smob of configuration context.
923 * \param group_s Group name as a string.
924 * \param key_s Key name as a string.
925 * \param value_s New value for parameter.
928 SCM_DEFINE (set_config_x
, "%set-config!", 4, 0, 0,
929 (SCM cfg_s
, SCM group_s
, SCM key_s
, SCM value_s
),
930 "Set a configuration parameter's value.")
932 ASSERT_CFG_GROUP_KEY (s_set_config_x
);
934 scm_dynwind_begin (0);
935 EdaConfig
*cfg
= edascm_to_config (cfg_s
);
936 char *group
= scm_to_utf8_string (group_s
);
937 scm_dynwind_free (group
);
938 char *key
= scm_to_utf8_string (key_s
);
939 scm_dynwind_free (key
);
941 /* Figure out what value is */
942 if (scm_is_string (value_s
)) {
943 char *value
= scm_to_utf8_string (value_s
);
944 scm_dynwind_free (value
);
945 eda_config_set_string (cfg
, group
, key
, value
);
946 } else if (scm_is_bool (value_s
)) {
947 gboolean value
= scm_is_true (value_s
);
948 eda_config_set_boolean (cfg
, group
, key
, value
);
949 } else if (scm_is_integer (value_s
) && scm_is_true (scm_exact_p (value_s
))) {
950 gint value
= scm_to_int (value_s
);
951 eda_config_set_int (cfg
, group
, key
, value
);
952 } else if (scm_is_real (value_s
)) {
953 gdouble value
= scm_to_double (value_s
);
954 eda_config_set_double (cfg
, group
, key
, value
);
956 } else if (scm_is_true (scm_list_p (value_s
))) {
957 /* Find out what sort of list it is, then process it accordingly. */
958 SCM first_s
= scm_car (value_s
);
959 int len
= scm_to_int (scm_length (value_s
));
963 if (scm_is_string (first_s
)) {
964 gchar
**value
= g_new0 (gchar
*, len
+ 1); /* null-terminated! */
965 scm_dynwind_unwind_handler ((void (*)(void *)) g_strfreev
, value
,
966 SCM_F_WIND_EXPLICITLY
);
967 for (curr_s
= value_s
; !scm_is_null (curr_s
); curr_s
= scm_cdr (curr_s
)) {
968 char *tmp
= scm_to_utf8_string (scm_car (curr_s
));
969 value
[i
++] = g_strdup (tmp
);
972 eda_config_set_string_list (cfg
, group
, key
,
973 (const gchar
* const *) value
, len
);
975 } else if (scm_is_bool (first_s
)) {
976 gboolean
*value
= g_new0 (gboolean
, len
);
977 scm_dynwind_unwind_handler (g_free
, value
, SCM_F_WIND_EXPLICITLY
);
978 for (curr_s
= value_s
; !scm_is_null (curr_s
); curr_s
= scm_cdr (curr_s
)) {
979 value
[i
++] = scm_is_true (scm_car (curr_s
));
981 eda_config_set_boolean_list (cfg
, group
, key
, value
, len
);
983 } else if (scm_is_integer (first_s
)
984 && scm_is_true (scm_exact_p (first_s
))) {
985 gint
*value
= g_new0 (gint
, len
);
986 scm_dynwind_unwind_handler (g_free
, value
, SCM_F_WIND_EXPLICITLY
);
987 for (curr_s
= value_s
; !scm_is_null (curr_s
); curr_s
= scm_cdr (curr_s
)) {
988 value
[i
++] = scm_to_int (scm_car (curr_s
));
990 eda_config_set_int_list (cfg
, group
, key
, value
, len
);
992 } else if (scm_is_real (first_s
)) {
993 gdouble
*value
= g_new0 (gdouble
, len
);
994 scm_dynwind_unwind_handler (g_free
, value
, SCM_F_WIND_EXPLICITLY
);
995 for (curr_s
= value_s
; !scm_is_null (curr_s
); curr_s
= scm_cdr (curr_s
)) {
996 value
[i
++] = scm_to_double (scm_car (curr_s
));
998 eda_config_set_double_list (cfg
, group
, key
, value
, len
);
1001 scm_wrong_type_arg (s_set_config_x
, SCM_ARG4
, value_s
);
1005 scm_wrong_type_arg (s_set_config_x
, SCM_ARG4
, value_s
);
1008 scm_remember_upto_here_1 (value_s
);
1013 /*! \brief Dispatch to a Scheme configuration change event handler.
1014 * \par Function Description
1015 * Dispatcher function used by the Scheme API to run Scheme procedures
1016 * when a configuration change occurs.
1019 edascm_config_event_dispatcher (EdaConfig
*cfg
, const char *group
,
1020 const char *key
, void *user_data
)
1022 SCM proc_s
= SCM_PACK ((scm_t_bits
) user_data
);
1023 SCM expr
= scm_list_4 (proc_s
,
1024 edascm_from_config (cfg
),
1025 scm_from_utf8_string (group
),
1026 scm_from_utf8_string (key
));
1028 g_scm_eval_protected (expr
, scm_interaction_environment ());
1029 scm_remember_upto_here_1 (expr
);
1032 /*! \brief Add a configuration change event handler.
1033 * \par Function Description
1034 * Add \a proc_s as a function to be called when configuration is
1035 * modified in the context \a cfg. \a proc_s will be called with the
1036 * following prototype:
1039 * (proc CFG GROUP KEY)
1042 * If \a proc_s causes an Scheme error to be raised, the error will be
1043 * caught and logged.
1045 * \note Scheme API: Implements the \%add-config-event! procedure in the
1046 * (geda core config) module.
1048 * \param cfg_s #EdaConfig smob of configuration context.
1049 * \param proc_s Procedure to add as configuration change handler.
1052 SCM_DEFINE (add_config_event_x
, "%add-config-event!", 2, 0, 0,
1053 (SCM cfg_s
, SCM proc_s
),
1054 "Add a configuration change event handler.")
1056 SCM_ASSERT (EDASCM_CONFIGP (cfg_s
), cfg_s
, SCM_ARG1
, s_add_config_event_x
);
1057 SCM_ASSERT (scm_is_true (scm_procedure_p (proc_s
)),
1058 proc_s
, SCM_ARG2
, s_add_config_event_x
);
1060 EdaConfig
*cfg
= edascm_to_config (cfg_s
);
1062 /* Test if proc_s was already connected. */
1063 guint signal_id
= g_signal_lookup ("config-changed", EDA_TYPE_CONFIG
);
1065 g_signal_handler_find (cfg
,
1066 G_SIGNAL_MATCH_FUNC
| G_SIGNAL_MATCH_DATA
1067 | G_SIGNAL_MATCH_ID
,
1071 edascm_config_event_dispatcher
,
1072 (gpointer
) SCM_UNPACK (proc_s
));
1077 /* Protect proc_s against garbage collection */
1078 g_signal_connect (cfg
, "config-changed",
1079 G_CALLBACK (edascm_config_event_dispatcher
),
1080 (gpointer
) SCM_UNPACK (scm_gc_protect_object (proc_s
)));
1084 /*! \brief Remove a configuration change event handler.
1085 * \par Function Description
1086 * Stop \a proc_s from being called when configuration is modified in
1087 * the context \a cfg.
1089 * \note Scheme API: Implements the \%remove-config-event! procedure
1090 * in the (geda core config) module.
1092 * \param cfg_s #EdaConfig smob of configuration context.
1093 * \param proc_s Procedure to remove as configuration change handler.
1096 SCM_DEFINE (remove_config_event_x
, "%remove-config-event!", 2, 0, 0,
1097 (SCM cfg_s
, SCM proc_s
),
1098 "Remove a configuration change event handler.")
1100 SCM_ASSERT (EDASCM_CONFIGP (cfg_s
), cfg_s
, SCM_ARG1
, s_add_config_event_x
);
1101 SCM_ASSERT (scm_is_true (scm_procedure_p (proc_s
)),
1102 proc_s
, SCM_ARG2
, s_add_config_event_x
);
1104 EdaConfig
*cfg
= edascm_to_config (cfg_s
);
1105 guint signal_id
= g_signal_lookup ("config-changed", EDA_TYPE_CONFIG
);
1107 g_signal_handlers_disconnect_matched (cfg
,
1109 | G_SIGNAL_MATCH_DATA
1110 | G_SIGNAL_MATCH_ID
,
1114 edascm_config_event_dispatcher
,
1115 (gpointer
) SCM_UNPACK (proc_s
));
1116 g_warn_if_fail (found
< 2);
1118 scm_gc_unprotect_object (proc_s
);
1124 * \brief Create the (geda core config) Scheme module.
1125 * \par Function Description
1126 * Defines procedures in the (geda core config) module. The module can
1127 * be accessed using (use-modules (geda core config)).
1130 init_module_geda_core_config ()
1132 /* Register the functions and symbols */
1133 #include "scheme_config.x"
1135 /* Add them to the module's public definitions. */
1136 scm_c_export (s_default_config_context
,
1137 s_system_config_context
,
1138 s_user_config_context
,
1139 s_path_config_context
,
1146 s_set_config_parent_x
,
1148 s_set_config_trusted_x
,
1150 s_config_has_group_p
,
1157 s_config_string_list
,
1158 s_config_boolean_list
,
1162 s_add_config_event_x
,
1163 s_remove_config_event_x
,
1168 * \brief Initialise the basic gEDA configuration manipulation procedures.
1169 * \par Function Description
1170 * Registers some Scheme procedures for working with #EdaConfig
1171 * smobs. Should only be called by edascm_init().
1174 edascm_init_config ()
1176 /* Define the (geda core object) module */
1177 scm_c_define_module ("geda core config",
1178 init_module_geda_core_config
,