summaryrefslogtreecommitdiff
path: root/libguile/options.c
diff options
context:
space:
mode:
authorLudovic Courtès <ludo@gnu.org>2008-09-10 22:33:40 +0200
committerLudovic Courtès <ludo@gnu.org>2008-09-10 22:33:40 +0200
commit4a4849dbe0ae1b731b408167f90222e05d1ca2bd (patch)
treecaa909b99ffb221e43408a3d19ad3e8209e3a96b /libguile/options.c
parent3ec17f28b8f96fa43218db83656c0d85b4f69d7c (diff)
parent032913739218c756f673bfb9c8f66ef9f8f02330 (diff)
downloadguile-4a4849dbe0ae1b731b408167f90222e05d1ca2bd.tar.gz
Merge commit '032913739218c756f673bfb9c8f66ef9f8f02330' into boehm-demers-weiser-gc
Conflicts: libguile/gc.c libguile/srcprop.c libguile/srcprop.h
Diffstat (limited to 'libguile/options.c')
-rw-r--r--libguile/options.c59
1 files changed, 42 insertions, 17 deletions
diff --git a/libguile/options.c b/libguile/options.c
index 47cf60a91..ae75e1318 100644
--- a/libguile/options.c
+++ b/libguile/options.c
@@ -95,11 +95,11 @@ static SCM protected_objects = SCM_EOL;
/* Return a list of the current option setting. The format of an
* option setting is described in the above documentation. */
static SCM
-get_option_setting (const scm_t_option options[], unsigned int n)
+get_option_setting (const scm_t_option options[])
{
unsigned int i;
SCM ls = SCM_EOL;
- for (i = 0; i != n; ++i)
+ for (i = 0; options[i].name; ++i)
{
switch (options[i].type)
{
@@ -123,12 +123,12 @@ get_option_setting (const scm_t_option options[], unsigned int n)
/* Return a list of sublists, where each sublist contains option name, value
* and documentation string. */
static SCM
-get_documented_option_setting (const scm_t_option options[], unsigned int n)
+get_documented_option_setting (const scm_t_option options[])
{
SCM ans = SCM_EOL;
unsigned int i;
- for (i = 0; i != n; ++i)
+ for (i = 0; options[i].name; ++i)
{
SCM ls = scm_cons (scm_from_locale_string (options[i].doc), SCM_EOL);
switch (options[i].type)
@@ -149,21 +149,36 @@ get_documented_option_setting (const scm_t_option options[], unsigned int n)
}
+static int
+options_length (scm_t_option options[])
+{
+ unsigned int i = 0;
+ for (; options[i].name != NULL; ++i)
+ ;
+
+ return i;
+}
+
/* Alters options according to the given option setting 'args'. The value of
* args is known to be a list, but it is not known whether the list is a well
* formed option setting, i. e. if for every non-boolean option a value is
* given. For this reason, the function applies all changes to a copy of the
* original setting in memory. Only if 'args' was successfully processed,
- * the new setting will overwrite the old one. */
+ * the new setting will overwrite the old one.
+ *
+ * If DRY_RUN is set, don't change anything. This is useful for trying out an option
+ * before entering a critical section.
+ */
static void
-change_option_setting (SCM args, scm_t_option options[], unsigned int n, const char *s)
+change_option_setting (SCM args, scm_t_option options[], const char *s,
+ int dry_run)
{
unsigned int i;
SCM locally_protected_args = args;
- SCM malloc_obj = scm_malloc_obj (n * sizeof (scm_t_bits));
+ SCM malloc_obj = scm_malloc_obj (options_length (options) * sizeof (scm_t_bits));
scm_t_bits *flags = (scm_t_bits *) SCM_MALLOCDATA (malloc_obj);
- for (i = 0; i != n; ++i)
+ for (i = 0; options[i].name; ++i)
{
if (options[i].type == SCM_OPTION_BOOLEAN)
flags[i] = 0;
@@ -176,7 +191,7 @@ change_option_setting (SCM args, scm_t_option options[], unsigned int n, const c
SCM name = SCM_CAR (args);
int found = 0;
- for (i = 0; i != n && !found; ++i)
+ for (i = 0; options[i].name && !found; ++i)
{
if (scm_is_eq (name, SCM_PACK (options[i].name)))
{
@@ -204,7 +219,10 @@ change_option_setting (SCM args, scm_t_option options[], unsigned int n, const c
args = SCM_CDR (args);
}
- for (i = 0; i != n; ++i)
+ if (dry_run)
+ return;
+
+ for (i = 0; options[i].name; ++i)
{
if (options[i].type == SCM_OPTION_SCM)
{
@@ -223,32 +241,39 @@ change_option_setting (SCM args, scm_t_option options[], unsigned int n, const c
SCM
-scm_options (SCM args, scm_t_option options[], unsigned int n, const char *s)
+scm_options (SCM args, scm_t_option options[], const char *s)
+{
+ return scm_options_try (args, options, s, 0);
+}
+
+SCM
+scm_options_try (SCM args, scm_t_option options[], const char *s,
+ int dry_run)
{
if (SCM_UNBNDP (args))
- return get_option_setting (options, n);
+ return get_option_setting (options);
else if (!SCM_NULL_OR_NIL_P (args) && !scm_is_pair (args))
/* Dirk:FIXME:: This criterion should be improved. IMO it is better to
* demand that args is #t if documentation should be shown than to say
* that every argument except a list will print out documentation. */
- return get_documented_option_setting (options, n);
+ return get_documented_option_setting (options);
else
{
SCM old_setting;
SCM_ASSERT (scm_is_true (scm_list_p (args)), args, 1, s);
- old_setting = get_option_setting (options, n);
- change_option_setting (args, options, n, s);
+ old_setting = get_option_setting (options);
+ change_option_setting (args, options, s, dry_run);
return old_setting;
}
}
void
-scm_init_opts (SCM (*func) (SCM), scm_t_option options[], unsigned int n)
+scm_init_opts (SCM (*func) (SCM), scm_t_option options[])
{
unsigned int i;
- for (i = 0; i != n; ++i)
+ for (i = 0; options[i].name; ++i)
{
SCM name = scm_from_locale_symbol (options[i].name);
options[i].name = (char *) SCM_UNPACK (name);