Changeset a54ffe6


Ignore:
Timestamp:
Feb 24, 2013, 6:01:35 PM (8 years ago)
Author:
Adam Glasgall <adam@crossproduct.net>
Branches:
master
Children:
ba5e919
Parents:
bbe7d4a (diff), 104a4eb (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:
Merge pull request #118 from davidben/perlvariables-n-plus-1

Merging perlvariables work, since all issues seem to have been addressed.
Files:
3 added
10 edited

Legend:

Unmodified
Added
Removed
  • Makefile.am

    rc266281 r353719a  
    3939
    4040CODELIST_SRCS=message.c mainwin.c popwin.c zephyr.c messagelist.c \
    41      commands.c global.c text.c fmtext.c editwin.c util.c logging.c \
     41     commands.c global.c text.c fmtext.c editwin.c \
     42     util.c logging.c \
    4243     perlconfig.c keys.c functions.c zwrite.c viewwin.c help.c filter.c \
    4344     regex.c history.c view.c dict.c variable.c filterelement.c pair.c \
     
    4546     aim.c buddy.c buddylist.c style.c errqueue.c \
    4647     zbuddylist.c popexec.c select.c wcwidth.c \
    47      mainpanel.c msgwin.c sepbar.c editcontext.c signal.c
     48     mainpanel.c msgwin.c sepbar.c editcontext.c signal.c closures.c
    4849
    4950NORMAL_SRCS = filterproc.c window.c windowcb.c
     
    5152BASE_SRCS = $(CODELIST_SRCS) $(NORMAL_SRCS)
    5253
    53 GEN_C = varstubs.c perlglue.c
    54 GEN_H = owl_prototypes.h
     54GEN_C = varstubs.c perlglue.c gmarshal_funcs.c
     55GEN_H = owl_prototypes.h gmarshal_funcs.h
    5556
    5657BUILT_SOURCES = $(GEN_C) $(GEN_H)
     
    7475        $(AM_V_GEN)perl $< $(sort $(filter-out $<,$+)) > $@
    7576
     77gmarshal_funcs.h: marshal_types
     78        glib-genmarshal --header $< > $@
     79gmarshal_funcs.c: marshal_types
     80        glib-genmarshal --body $< > $@
     81
    7682# For emacs flymake-mode
    7783check-syntax: proto
  • commands.c

    r8258ea5 r3b9ca71  
    16041604  if (v == NULL) {
    16051605    if (!silent) owl_function_error("Unknown variable '%s'", var);
    1606   } else if (requirebool && owl_variable_get_type(v) != OWL_VARIABLE_BOOL) {
     1606  } else if (requirebool && !v->takes_on_off) {
    16071607    if (!silent) owl_function_error("Variable '%s' is not a boolean", var);
    16081608  } else {
     
    16331633  if (v == NULL) {
    16341634    if (!silent) owl_function_error("Unknown variable '%s'", var);
    1635   } else if (owl_variable_get_type(v) != OWL_VARIABLE_BOOL) {
     1635  } else if (!v->takes_on_off) {
    16361636    if (!silent) owl_function_error("Variable '%s' is not a boolean", var);
    16371637  } else {
  • configure.ac

    r58b6ce5 r06e04a9  
    127127AX_PROG_PERL_MODULES([PAR],,
    128128                     [AC_MSG_WARN([PAR.pm not found. Loadable modules will be disabled.])])
     129AX_PROG_PERL_MODULES([ExtUtils::Depends],,
     130                     [AC_MSG_ERROR([cannot find perl module ExtUtils::Depends])])
    129131
    130132dnl Add CFLAGS and LIBS for glib-2.0
     
    139141   prefix="${ac_default_prefix}"
    140142fi
     143
     144dnl Add CFLAGS for glib-perl
     145GLIB_PERL_CFLAGS=`perl -MExtUtils::Depends -e 'my $e = ExtUtils::Depends->new("BarnOwl","Glib"); my %h = $e->get_makefile_vars; print $h{"INC"}'`
     146AC_MSG_NOTICE([Adding glib-perl CFLAGS ${GLIB_PERL_CFLAGS}])
     147AM_CFLAGS="${GLIB_PERL_CFLAGS} ${AM_CFLAGS}"
    141148
    142149dnl Checks for typedefs, structures, and compiler characteristics.
  • owl.h

    rc42a8d1 rbbc31e4  
    235235  char *name;
    236236  int   type;  /* OWL_VARIABLE_* */
    237   void *pval_default;  /* for types other and string */
    238   int   ival_default;  /* for types int and bool     */
    239   const char *validsettings;    /* documentation of valid settings */
     237  char *default_str;            /* the default value as a string */
     238  char *validsettings;          /* documentation of valid settings */
    240239  char *summary;                /* summary of usage */
    241240  char *description;            /* detailed description */
    242   void *val;                    /* current value */
    243   int  (*validate_fn)(const struct _owl_variable *v, const void *newval);
     241  bool takes_on_off;            /* allow passing on/off in argument-less set/unset */
     242  GClosure *set_fromstring_fn;
     243                                /* sets the variable to a value
     244                                 * of the appropriate type.
     245                                 * unless documented, this
     246                                 * should make a copy.
     247                                 * returns 0 on success. */
     248  GClosure *get_tostring_fn;
     249                                /* converts val to a string;
     250                                 * caller must free the result */
     251
     252  /* These are only valid for OWL_VARIABLE_{INT,BOOL,STRING} */
     253  GValue val;                   /* current value, if default get_fn/set_fn */
     254
     255  GCallback get_fn;
     256                                /* returns a reference to the current value.
     257                                 * WARNING:  this approach is hard to make
     258                                 * thread-safe... */
     259  GCallback validate_fn;
    244260                                /* returns 1 if newval is valid */
    245   int  (*set_fn)(struct _owl_variable *v, const void *newval);
     261  GCallback set_fn;
    246262                                /* sets the variable to a value
    247                                  * of the appropriate type.
    248                                  * unless documented, this
    249                                  * should make a copy.
    250                                  * returns 0 on success. */
    251   int  (*set_fromstring_fn)(struct _owl_variable *v, const char *newval);
    252                                 /* sets the variable to a value
    253                                  * of the appropriate type.
    254                                  * unless documented, this
    255                                  * should make a copy.
    256                                  * returns 0 on success. */
    257   const void *(*get_fn)(const struct _owl_variable *v);
    258                                 /* returns a reference to the current value.
    259                                  * WARNING:  this approach is hard to make
    260                                  * thread-safe... */
    261   CALLER_OWN char *(*get_tostring_fn)(const struct _owl_variable *v, const void *val);
    262                                 /* converts val to a string;
    263                                  * caller must free the result */
    264   void (*delete_fn)(struct _owl_variable *v);
    265                                 /* frees val as needed */
     263                                 * of the appropriate type.
     264                                 * unless documented, this
     265                                 * should make a copy.
     266                                 * returns 0 on success. */
    266267} owl_variable;
     268
    267269
    268270typedef struct _owl_input {
     
    614616#endif
    615617
     618/* We have to dynamically bind these ourselves */
     619extern gboolean (*gvalue_from_sv) (GValue * value, SV * sv);
     620extern SV * (*sv_from_gvalue) (const GValue * value);
     621extern GClosure * (*perl_closure_new) (SV * callback, SV * data, gboolean swap);
     622
     623
    616624#endif /* INC_BARNOWL_OWL_H */
  • perl/lib/BarnOwl.pm

    r374089a r104a4eb  
    1818                    new_command
    1919                    new_variable_int new_variable_bool new_variable_string
     20                    new_variable_enum
    2021                    quote redisplay);
    2122our %EXPORT_TAGS = (all => \@EXPORT_OK);
     
    402403=head2 new_variable_string NAME [{ARGS}]
    403404
    404 Add a new owl variable, either an int, a bool, or a string, with the
     405=head2 new_variable_enum NAME [{ARGS}]
     406
     407Add a new owl variable, either an int, a bool, a string, or an enum with the
    405408specified name.
    406409
    407 ARGS can optionally contain the following keys:
     410For new_variable_enum, ARGS is required to contain a validsettings key pointing
     411to an array reference. For all four, it can optionally contain the following
     412keys:
    408413
    409414=over 4
     
    423428=back
    424429
     430In addition, new_variable_string optionally accepts a string validsettings
     431parameter, in case people want to set it to "<path>".
     432
    425433=cut
    426434
    427435sub new_variable_int {
    428     unshift @_, \&BarnOwl::Internal::new_variable_int, 0;
    429     goto \&_new_variable;
     436    my ($name, $args) = @_;
     437    my $storage = defined($args->{default}) ? $args->{default} : 0;
     438    BarnOwl::new_variable_full($name, {
     439            %{$args},
     440            get_tostring => sub { "$storage" },
     441            set_fromstring => sub {
     442                die "Expected integer" unless $_[0] =~ /^-?[0-9]+$/;
     443                $storage = 0 + $_[0];
     444            },
     445            validsettings => "<int>",
     446            takes_on_off => 0,
     447        });
    430448}
    431449
    432450sub new_variable_bool {
    433     unshift @_, \&BarnOwl::Internal::new_variable_bool, 0;
    434     goto \&_new_variable;
     451    my ($name, $args) = @_;
     452    my $storage = defined($args->{default}) ? $args->{default} : 0;
     453    BarnOwl::new_variable_full($name, {
     454            %{$args},
     455            get_tostring => sub { $storage ? "on" : "off" },
     456            set_fromstring => sub {
     457                die "Valid settings are on/off" unless $_[0] eq "on" || $_[0] eq "off";
     458                $storage = $_[0] eq "on";
     459            },
     460            validsettings => "on,off",
     461            takes_on_off => 1,
     462        });
    435463}
    436464
    437465sub new_variable_string {
    438     unshift @_, \&BarnOwl::Internal::new_variable_string, "";
    439     goto \&_new_variable;
    440 }
    441 
    442 sub _new_variable {
    443     my $func = shift;
    444     my $default_default = shift;
     466    my ($name, $args) = @_;
     467    my $storage = defined($args->{default}) ? $args->{default} : "";
     468    BarnOwl::new_variable_full($name, {
     469            # Allow people to override this one if they /reaaally/ want to for
     470            # some reason. Though we still reserve the right to interpret this
     471            # value in interesting ways for tab-completion purposes.
     472            validsettings => "<string>",
     473            %{$args},
     474            get_tostring => sub { $storage },
     475            set_fromstring => sub { $storage = $_[0]; },
     476            takes_on_off => 0,
     477        });
     478}
     479
     480sub new_variable_enum {
     481    my ($name, $args) = @_;
     482
     483    # Gather the valid settings.
     484    die "validsettings is required" unless defined($args->{validsettings});
     485    my %valid;
     486    map { $valid{$_} = 1 } @{$args->{validsettings}};
     487
     488    my $storage = (defined($args->{default}) ?
     489                   $args->{default} :
     490                   $args->{validsettings}->[0]);
     491    BarnOwl::new_variable_full($name, {
     492            %{$args},
     493            get_tostring => sub { $storage },
     494            set_fromstring => sub {
     495                die "Invalid input" unless $valid{$_[0]};
     496                $storage = $_[0];
     497            },
     498            validsettings => join(",", @{$args->{validsettings}})
     499        });
     500}
     501
     502=head2 new_variable_full NAME {ARGS}
     503
     504Create a variable, in full generality. The keyword arguments have types below:
     505
     506 get_tostring : ()  -> string
     507 set_fromstring : string -> int
     508 -- optional --
     509 summary : string
     510 description : string
     511 validsettings : string
     512 takes_on_off : int
     513
     514The get/set functions are required. Note that the caller manages storage for the
     515variable. get_tostring/set_fromstring both convert AND store the value.
     516set_fromstring dies on failure.
     517
     518If the variable takes parameters 'on' and 'off' (i.e. is boolean-looking), set
     519takes_on_off to 1. This makes :set VAR and :unset VAR work. set_fromstring will
     520be called with those arguments.
     521
     522=cut
     523
     524sub new_variable_full {
    445525    my $name = shift;
    446526    my $args = shift || {};
    447527    my %args = (
    448         summary     => "",
     528        summary => "",
    449529        description => "",
    450         default     => $default_default,
     530        takes_on_off => 0,
     531        validsettings => "<string>",
    451532        %{$args});
    452     $func->($name, $args{default}, $args{summary}, $args{description});
     533
     534    die "get_tostring required" unless $args{get_tostring};
     535    die "set_fromstring required" unless $args{set_fromstring};
     536
     537    # Strip off the bogus dummy argument. Aargh perl-Glib.
     538    my $get_tostring_fn = sub { $args{get_tostring}->() };
     539    my $set_fromstring_fn = sub {
     540      my ($dummy, $val) = @_;
     541      # Translate from user-supplied die-on-failure callback to expected
     542      # non-zero on error. Less of a nuisance than interacting with ERRSV.
     543      eval { $args{set_fromstring}->($val) };
     544      # TODO: Consider changing B::I::new_variable to expect string|NULL with
     545      # string as the error message. That can then be translated to a GError in
     546      # owl_variable_set_fromstring. For now the string is ignored.
     547      return ($@ ? -1 : 0);
     548    };
     549
     550    BarnOwl::Internal::new_variable($name, $args{summary}, $args{description}, $args{validsettings},
     551                                    $args{takes_on_off}, $get_tostring_fn, $set_fromstring_fn, undef);
    453552}
    454553
  • perlconfig.c

    r6401db3 re5210c9  
    331331  char *err;
    332332  const char *args[4] = {"", "-e", "0;", NULL};
     333  const char *dlerr;
    333334  AV *inc;
    334335  char *path;
     
    388389  g_free(path);
    389390
     391  /* Load up perl-Glib. */
     392  eval_pv("use Glib;", FALSE);
     393
     394  /* Now, before BarnOwl tries to use them, get the relevant function pointers out. */
     395  dlerr = owl_closure_init();
     396  if (dlerr) {
     397    return g_strdup(dlerr);
     398  }
     399
     400  /* And now it's safe to import BarnOwl. */
    390401  eval_pv("use BarnOwl;", FALSE);
    391402
  • perlglue.xs

    r374089a r3b9ca71  
    402402           }
    403403
    404 void
    405 new_variable_string(name, ival, summ, desc)
    406         const char * name
    407         const char * ival
    408         const char * summ
    409         const char * desc
    410         CODE:
    411         owl_variable_dict_newvar_string(owl_global_get_vardict(&g),
    412                                         name,
    413                                         summ,
    414                                         desc,
    415                                         ival);
    416 
    417 void
    418 new_variable_int(name, ival, summ, desc)
    419         const char * name
    420         int ival
    421         const char * summ
    422         const char * desc
    423         CODE:
    424         owl_variable_dict_newvar_int(owl_global_get_vardict(&g),
    425                                      name,
    426                                      summ,
    427                                      desc,
    428                                      ival);
    429 
    430 void
    431 new_variable_bool(name, ival, summ, desc)
    432         const char * name
    433         int ival
    434         const char * summ
    435         const char * desc
    436         CODE:
    437         owl_variable_dict_newvar_bool(owl_global_get_vardict(&g),
    438                                       name,
    439                                       summ,
    440                                       desc,
    441                                       ival);
     404
     405MODULE = BarnOwl                PACKAGE = BarnOwl::Internal
     406
     407void
     408new_variable(name, summary, description, validsettings, takes_on_off, get_tostring_fn, set_fromstring_fn, data)
     409    const char *name
     410    const char *summary
     411    const char *description
     412    const char *validsettings
     413    int takes_on_off
     414    SV *get_tostring_fn
     415    SV *set_fromstring_fn
     416    SV *data
     417    CODE:
     418{
     419        /* data is somewhat redundant given we can create closures, but oh
     420         * well. Might be convenient sometimes. */
     421        if(!SV_IS_CODEREF(get_tostring_fn)) {
     422                croak("To-string function must be a coderef!");
     423        }
     424        if(!SV_IS_CODEREF(set_fromstring_fn)) {
     425                croak("From-string function must be a coderef!");
     426        }
     427
     428        owl_variable_dict_newvar_other(owl_global_get_vardict(&g),
     429                                       name, summary, description, validsettings, takes_on_off,
     430                                       perl_closure_new(get_tostring_fn, data, false),
     431                                       perl_closure_new(set_fromstring_fn, data, false));
     432}
    442433
    443434void
  • tester.c

    r6a20996 r6a8b519  
    337337  int numfailed=0;
    338338  char *value;
    339   const void *v;
    340339
    341340  printf("# BEGIN testing owl_variable\n");
    342   FAIL_UNLESS("setup", 0==owl_variable_dict_setup(&vd));
     341  owl_variable_dict_setup(&vd);
    343342
    344343  FAIL_UNLESS("get bool var", NULL != (var = owl_variable_get_var(&vd, "rxping")));
     
    377376  FAIL_UNLESS("get int 7", 9 == owl_variable_get_int(var));
    378377
    379   owl_variable_dict_newvar_string(&vd, "stringvar", "", "", "testval");
     378  FAIL_UNLESS("get enum var", NULL != (var = owl_variable_get_var(&vd, "scrollmode")));
     379  FAIL_UNLESS("get enum", OWL_SCROLLMODE_NORMAL == owl_variable_get_int(var));
     380  FAIL_UNLESS("get enum as string",
     381              !strcmp((value = owl_variable_get_tostring(var)), "normal"));
     382  g_free(value);
     383  FAIL_UNLESS("set enum 1", 0 == owl_variable_set_int(var, OWL_SCROLLMODE_TOP));
     384  FAIL_UNLESS("get enum 1", OWL_SCROLLMODE_TOP == owl_variable_get_int(var));
     385  FAIL_UNLESS("set enum 2a", -1 == owl_variable_set_int(var, -1));
     386  FAIL_UNLESS("set enum 2b", -1 == owl_variable_set_int(var, OWL_SCROLLMODE_PAGEDCENTER + 1));
     387  FAIL_UNLESS("get enum 2", OWL_SCROLLMODE_TOP == owl_variable_get_int(var));
     388  FAIL_UNLESS("set enum 3", 0 == owl_variable_set_fromstring(var, "center", 0));
     389  FAIL_UNLESS("get enum 4", OWL_SCROLLMODE_CENTER == owl_variable_get_int(var));
     390  FAIL_UNLESS("set enum 5", -1 == owl_variable_set_fromstring(var, "bogus", 0));
     391  FAIL_UNLESS("set enum 6", -1 == owl_variable_set_fromstring(var, "", 0));
     392  FAIL_UNLESS("get enum 7", OWL_SCROLLMODE_CENTER == owl_variable_get_int(var));
     393
     394  owl_variable_dict_newvar_string(&vd, "stringvar", "testval", "", "");
    380395  FAIL_UNLESS("get new string var", NULL != (var = owl_variable_get_var(&vd, "stringvar")));
    381   FAIL_UNLESS("get new string var", NULL != (v = owl_variable_get(var)));
    382396  FAIL_UNLESS("get new string val", !strcmp("testval", owl_variable_get_string(var)));
    383397  owl_variable_set_string(var, "new val");
    384398  FAIL_UNLESS("update string val", !strcmp("new val", owl_variable_get_string(var)));
    385399
    386   owl_variable_dict_newvar_int(&vd, "intvar", "", "", 47);
     400  owl_variable_dict_newvar_int(&vd, "intvar", 47, "", "");
    387401  FAIL_UNLESS("get new int var", NULL != (var = owl_variable_get_var(&vd, "intvar")));
    388   FAIL_UNLESS("get new int var", NULL != (v = owl_variable_get(var)));
    389402  FAIL_UNLESS("get new int val", 47 == owl_variable_get_int(var));
    390403  owl_variable_set_int(var, 17);
    391404  FAIL_UNLESS("update int val", 17 == owl_variable_get_int(var));
    392405
    393   owl_variable_dict_newvar_bool(&vd, "boolvar", "", "", 1);
     406  owl_variable_dict_newvar_bool(&vd, "boolvar", true, "", "");
    394407  FAIL_UNLESS("get new bool var", NULL != (var = owl_variable_get_var(&vd, "boolvar")));
    395   FAIL_UNLESS("get new bool var", NULL != (v = owl_variable_get(var)));
    396408  FAIL_UNLESS("get new bool val", owl_variable_get_bool(var));
    397409  owl_variable_set_bool_off(var);
    398410  FAIL_UNLESS("update bool val", !owl_variable_get_bool(var));
    399411
    400   owl_variable_dict_newvar_string(&vd, "nullstringvar", "", "", NULL);
     412  owl_variable_dict_newvar_string(&vd, "nullstringvar", NULL, "", "");
    401413  FAIL_UNLESS("get new string (NULL) var", NULL != (var = owl_variable_get_var(&vd, "nullstringvar")));
    402414  FAIL_UNLESS("get string (NULL)", NULL == (value = owl_variable_get_tostring(var)));
     
    405417  FAIL_UNLESS("get string (NULL) 2", NULL == (value = owl_variable_get_tostring(var)));
    406418  g_free(value);
     419
     420  owl_variable_dict_newvar_enum(&vd, "enumvar", 0, "", "", "a,b,c,d");
     421  FAIL_UNLESS("get new enum var", NULL != (var = owl_variable_get_var(&vd, "enumvar")));
     422  FAIL_UNLESS("get new enum val", 0 == owl_variable_get_int(var));
     423  owl_variable_set_fromstring(var, "c", 0);
     424  FAIL_UNLESS("update enum val", 2 == owl_variable_get_int(var));
    407425
    408426  owl_variable_dict_cleanup(&vd);
  • variable.c

    r8258ea5 r6a8b519  
    11#include "owl.h"
    22#include <stdio.h>
    3 
    4 #define OWLVAR_BOOL(name,default,summary,description) \
    5         { g_strdup(name), OWL_VARIABLE_BOOL, NULL, default, "on,off", g_strdup(summary), g_strdup(description), NULL, \
    6         NULL, NULL, NULL, NULL, NULL, NULL }
    7 
    8 #define OWLVAR_BOOL_FULL(name,default,summary,description,validate,set,get) \
    9         { g_strdup(name), OWL_VARIABLE_BOOL, NULL, default, "on,off", g_strdup(summary), g_strdup(description), NULL, \
    10         validate, set, NULL, get, NULL, NULL }
    11 
    12 #define OWLVAR_INT(name,default,summary,description) \
    13         { g_strdup(name), OWL_VARIABLE_INT, NULL, default, "<int>", g_strdup(summary), g_strdup(description), NULL, \
    14         NULL, NULL, NULL, NULL, NULL, NULL }
     3#include "gmarshal_funcs.h"
     4
     5/* TODO(davidben): When we can require 2.30 and up, remove this. */
     6#ifndef G_VALUE_INIT
     7#define G_VALUE_INIT { 0, { { 0 } } }
     8#endif
     9
     10typedef const char *(*get_string_t)(const owl_variable *);
     11typedef int (*get_int_t)(const owl_variable *);
     12typedef bool (*get_bool_t)(const owl_variable *);
     13
     14typedef int (*set_string_t)(owl_variable *, const char *);
     15typedef int (*set_int_t)(owl_variable *, int);
     16typedef int (*set_bool_t)(owl_variable *, bool);
     17
     18typedef int (*validate_string_t)(const owl_variable *, const char *);
     19typedef int (*validate_int_t)(const owl_variable *, int);
     20typedef int (*validate_bool_t)(const owl_variable *, bool);
     21
     22static void owl_variable_dict_newvar_bool_full(owl_vardict *vd,
     23                                               const char *name,
     24                                               bool default_val,
     25                                               const char *summary,
     26                                               const char *description,
     27                                               validate_bool_t validate_fn,
     28                                               set_bool_t set_fn,
     29                                               get_bool_t get_fn);
     30
     31static void owl_variable_dict_newvar_string_full(owl_vardict *vd,
     32                                                 const char *name,
     33                                                 const char *default_val,
     34                                                 const char *summary,
     35                                                 const char *description,
     36                                                 const char *validsettings,
     37                                                 validate_string_t validate_fn,
     38                                                 set_string_t set_fn,
     39                                                 get_string_t get_fn);
     40
     41static void owl_variable_dict_newvar_int_full(owl_vardict *vd,
     42                                              const char *name,
     43                                              int default_val,
     44                                              const char *summary,
     45                                              const char *description,
     46                                              const char *validsettings,
     47                                              validate_int_t validate_fn,
     48                                              set_int_t set_fn,
     49                                              get_int_t get_fn);
     50
     51static void owl_variable_dict_newvar_enum_full(owl_vardict *vd,
     52                                               const char *name,
     53                                               int default_val,
     54                                               const char *summary,
     55                                               const char *description,
     56                                               const char *validsettings,
     57                                               validate_int_t validate_fn,
     58                                               set_int_t set_fn,
     59                                               get_int_t get_fn);
     60
     61#define OWLVAR_BOOL(name, default, summary, description) \
     62        owl_variable_dict_newvar_bool(vd, name, default, summary, description)
     63
     64#define OWLVAR_BOOL_FULL(name, default, summary, description, validate, set, get) \
     65        owl_variable_dict_newvar_bool_full(vd, name, default, summary, description, \
     66                                           validate, set, get)
     67
     68#define OWLVAR_INT(name, default, summary, description) \
     69        owl_variable_dict_newvar_int(vd, name, default, summary, description)
    1570
    1671#define OWLVAR_INT_FULL(name,default,summary,description,validset,validate,set,get) \
    17         { g_strdup(name), OWL_VARIABLE_INT, NULL, default, validset, g_strdup(summary), g_strdup(description), NULL, \
    18         validate, set, NULL, get, NULL, NULL }
    19 
    20 #define OWLVAR_PATH(name,default,summary,description) \
    21         { g_strdup(name), OWL_VARIABLE_STRING, g_strdup(default), 0, "<path>", g_strdup(summary), g_strdup(description),  NULL, \
    22         NULL, NULL, NULL, NULL, NULL, NULL }
    23 
    24 #define OWLVAR_STRING(name,default,summary,description) \
    25         { g_strdup(name), OWL_VARIABLE_STRING, g_strdup(default), 0, "<string>", g_strdup(summary), g_strdup(description), NULL, \
    26         NULL, NULL, NULL, NULL, NULL, NULL }
    27 
    28 #define OWLVAR_STRING_FULL(name,default,validset,summary,description,validate,set,get) \
    29         { g_strdup(name), OWL_VARIABLE_STRING, g_strdup(default), 0, validset, g_strdup(summary), g_strdup(description), NULL, \
    30         validate, set, NULL, get, NULL, NULL }
     72        owl_variable_dict_newvar_int_full(vd, name, default, summary, description, \
     73                                          validset, validate, set, get)
     74
     75#define OWLVAR_PATH(name, default, summary, description) \
     76        owl_variable_dict_newvar_path(vd, name, default, summary, description)
     77
     78#define OWLVAR_STRING(name, default, summary, description) \
     79        owl_variable_dict_newvar_string(vd, name, default, summary, description)
     80
     81#define OWLVAR_STRING_FULL(name, default, validset, summary, description, validate, set, get) \
     82        owl_variable_dict_newvar_string_full(vd, name, default, summary, description, \
     83                                             validset, validate, set, get)
    3184
    3285/* enums are really integers, but where validset is a comma-separated
    3386 * list of strings which can be specified.  The tokens, starting at 0,
    3487 * correspond to the values that may be specified. */
    35 #define OWLVAR_ENUM(name,default,summary,description,validset) \
    36         { g_strdup(name), OWL_VARIABLE_INT, NULL, default, validset, g_strdup(summary), g_strdup(description), NULL, \
    37         owl_variable_enum_validate, \
    38         NULL, owl_variable_enum_set_fromstring, \
    39         NULL, owl_variable_enum_get_tostring, \
    40         NULL }
     88#define OWLVAR_ENUM(name, default, summary, description, validset) \
     89        owl_variable_dict_newvar_enum(vd, name, default, summary, description, validset)
    4190
    4291#define OWLVAR_ENUM_FULL(name,default,summary,description,validset,validate, set, get) \
    43         { g_strdup(name), OWL_VARIABLE_INT, NULL, default, validset, g_strdup(summary), g_strdup(description), NULL, \
    44         validate, \
    45         set, owl_variable_enum_set_fromstring, \
    46         get, owl_variable_enum_get_tostring, \
    47         NULL }
    48 
    49 int owl_variable_add_defaults(owl_vardict *vd)
    50 {
    51   owl_variable variables_to_init[] = {
    52 
     92        owl_variable_dict_newvar_enum_full(vd, name, default, summary, description, \
     93                                           validset, validate, set, get)
     94
     95void owl_variable_add_defaults(owl_vardict *vd)
     96{
    5397  OWLVAR_STRING( "personalbell" /* %OwlVarStub */, "off",
    5498                 "ring the terminal bell when personal messages are received",
    5599                 "Can be set to 'on', 'off', or the name of a filter which\n"
    56                  "messages need to match in order to ring the bell"),
     100                 "messages need to match in order to ring the bell");
    57101
    58102  OWLVAR_BOOL( "bell" /* %OwlVarStub */, 1,
    59                "enable / disable the terminal bell", "" ),
     103               "enable / disable the terminal bell", "" );
    60104
    61105  OWLVAR_BOOL_FULL( "debug" /* %OwlVarStub */, OWL_DEBUG,
     
    63107                    "If set to 'on', debugging messages are logged to the\n"
    64108                    "file specified by the debugfile variable.\n",
    65                     NULL, owl_variable_debug_set, NULL),
     109                    NULL, owl_variable_debug_set, NULL);
    66110
    67111  OWLVAR_BOOL( "startuplogin" /* %OwlVarStub */, 1,
    68                "send a login message when BarnOwl starts", "" ),
     112               "send a login message when BarnOwl starts", "" );
    69113
    70114  OWLVAR_BOOL( "shutdownlogout" /* %OwlVarStub */, 1,
    71                "send a logout message when BarnOwl exits", "" ),
     115               "send a logout message when BarnOwl exits", "" );
    72116
    73117  OWLVAR_BOOL( "rxping" /* %OwlVarStub */, 0,
    74                "display received pings", "" ),
     118               "display received pings", "" );
    75119
    76120  OWLVAR_BOOL( "txping" /* %OwlVarStub */, 1,
    77                "send pings", "" ),
     121               "send pings", "" );
    78122
    79123  OWLVAR_BOOL( "sepbar_disable" /* %OwlVarStub */, 0,
    80                "disable printing information in the separator bar", "" ),
     124               "disable printing information in the separator bar", "" );
    81125
    82126  OWLVAR_BOOL( "smartstrip" /* %OwlVarStub */, 1,
    83                "strip kerberos instance for reply", ""),
     127               "strip kerberos instance for reply", "");
    84128
    85129  OWLVAR_BOOL( "newlinestrip" /* %OwlVarStub */, 1,
    86                "strip leading and trailing newlines", ""),
     130               "strip leading and trailing newlines", "");
    87131
    88132  OWLVAR_BOOL( "displayoutgoing" /* %OwlVarStub */, 1,
    89                "display outgoing messages", "" ),
     133               "display outgoing messages", "" );
    90134
    91135  OWLVAR_BOOL( "loginsubs" /* %OwlVarStub */, 1,
    92                "load logins from .anyone on startup", "" ),
     136               "load logins from .anyone on startup", "" );
    93137
    94138  OWLVAR_BOOL( "logging" /* %OwlVarStub */, 0,
     
    97141               "logged in the directory specified\n"
    98142               "by the 'logpath' variable.  The filename in that\n"
    99                "directory is derived from the sender of the message.\n" ),
     143               "directory is derived from the sender of the message.\n" );
    100144
    101145  OWLVAR_BOOL( "classlogging" /* %OwlVarStub */, 0,
     
    105149               "by the 'classlogpath' variable.\n"
    106150               "The filename in that directory is derived from\n"
    107                "the name of the class to which the message was sent.\n" ),
     151               "the name of the class to which the message was sent.\n" );
    108152
    109153  OWLVAR_ENUM( "loggingdirection" /* %OwlVarStub */, OWL_LOGGING_DIRECTION_BOTH,
     
    114158               "is selected both incoming and outgoing messages are\n"
    115159               "logged.",
    116                "both,in,out"),
     160               "both,in,out");
    117161
    118162  OWLVAR_BOOL_FULL( "colorztext" /* %OwlVarStub */, 1,
    119163                    "allow @color() in zephyrs to change color",
    120                     NULL, NULL, owl_variable_colorztext_set, NULL),
     164                    NULL, NULL, owl_variable_colorztext_set, NULL);
    121165
    122166  OWLVAR_BOOL( "fancylines" /* %OwlVarStub */, 1,
     
    124168               "If turned off, dashes, pipes and pluses will be used\n"
    125169               "to draw lines on the screen.  Useful when the terminal\n"
    126                "is causing problems" ),
     170               "is causing problems" );
    127171
    128172  OWLVAR_BOOL( "zcrypt" /* %OwlVarStub */, 1,
    129173               "Do automatic zcrypt processing",
    130                "" ),
     174               "" );
    131175
    132176  OWLVAR_BOOL_FULL( "pseudologins" /* %OwlVarStub */, 0,
     
    136180                    "but sent no login message, or a user is not present that sent no\n"
    137181                    "logout message, a pseudo login or logout message will be created\n",
    138                     NULL, owl_variable_pseudologins_set, NULL),
     182                    NULL, owl_variable_pseudologins_set, NULL);
    139183
    140184  OWLVAR_BOOL( "ignorelogins" /* %OwlVarStub */, 0,
     
    142186               "When this is enabled, BarnOwl will print login and logout notifications\n"
    143187               "for AIM, zephyr, or other protocols.  If disabled BarnOwl will not print\n"
    144                "login or logout notifications.\n"),
     188               "login or logout notifications.\n");
    145189
    146190  OWLVAR_STRING( "logfilter" /* %OwlVarStub */, "",
     
    151195                 "variables like logging, classlogging, loglogins, loggingdirection,\n"
    152196                 "etc.  If you want this variable to control all logging, make sure\n"
    153                  "all other logging variables are in their default state.\n"),
     197                 "all other logging variables are in their default state.\n");
    154198
    155199  OWLVAR_BOOL( "loglogins" /* %OwlVarStub */, 0,
     
    157201               "When this is enabled, BarnOwl will log login and logout notifications\n"
    158202               "for AIM, zephyr, or other protocols.  If disabled BarnOwl will not print\n"
    159                "login or logout notifications.\n"),
     203               "login or logout notifications.\n");
    160204
    161205  OWLVAR_ENUM_FULL( "disable-ctrl-d" /* %OwlVarStub:lockout_ctrld */, 1,
     
    169213                    "in the editmulti keymap.\n",
    170214                    "off,middle,on",
    171                     NULL, owl_variable_disable_ctrl_d_set, NULL),
     215                    NULL, owl_variable_disable_ctrl_d_set, NULL);
    172216
    173217  OWLVAR_PATH( "logpath" /* %OwlVarStub */, "~/zlog/people",
    174218               "path for logging personal zephyrs",
    175219               "Specifies a directory which must exist.\n"
    176                "Files will be created in the directory for each sender.\n"),
     220               "Files will be created in the directory for each sender.\n");
    177221
    178222  OWLVAR_PATH( "classlogpath" /* %OwlVarStub:classlogpath */, "~/zlog/class",
    179223               "path for logging class zephyrs",
    180224               "Specifies a directory which must exist.\n"
    181                "Files will be created in the directory for each class.\n"),
     225               "Files will be created in the directory for each class.\n");
    182226
    183227  OWLVAR_PATH( "debug_file" /* %OwlVarStub */, OWL_DEBUG_FILE,
    184228               "path for logging debug messages when debugging is enabled",
    185229               "This file will be logged to if 'debug' is set to 'on'.\n"
    186                "BarnOwl will append a dot and the current process's pid to the filename."),
     230               "BarnOwl will append a dot and the current process's pid to the filename.");
    187231 
    188232  OWLVAR_PATH( "zsigproc" /* %OwlVarStub:zsigproc */, NULL,
     
    192236               "See the documentation for 'zsig' for more information about\n"
    193237               "how the outgoing zsig is chosen."
    194                ),
     238               );
    195239
    196240  OWLVAR_PATH( "newmsgproc" /* %OwlVarStub:newmsgproc */, NULL,
     
    198242               "The named program will be run when BarnOwl receives new\n"
    199243               "messages.  It will not be run again until the first\n"
    200                "instance exits"),
     244               "instance exits");
    201245
    202246  OWLVAR_STRING( "zsender" /* %OwlVarStub */, "",
     
    205249         "zephyrs.  If this is unset, it will use your Kerberos\n"
    206250         "principal. Note that customizing the sender name will\n"
    207          "cause your zephyrs to be sent unauthenticated."),
     251         "cause your zephyrs to be sent unauthenticated.");
    208252
    209253  OWLVAR_STRING( "zsigfunc" /* %OwlVarStub */, "BarnOwl::default_zephyr_signature()",
     
    212256                 "explicit zsig.  The default setting implements the policy\n"
    213257                 "described in the documentation for the 'zsig' variable.\n"
    214                  "See also BarnOwl::random_zephyr_signature().\n"),
     258                 "See also BarnOwl::random_zephyr_signature().\n");
    215259
    216260  OWLVAR_STRING( "zsig" /* %OwlVarStub */, "",
     
    219263                 "unset, 'zsigproc' will be run to generate a zsig. If that is\n"
    220264                 "also unset, the 'zwrite-signature' zephyr variable will be\n"
    221                  "used instead.\n"),
     265                 "used instead.\n");
    222266
    223267  OWLVAR_STRING( "appendtosepbar" /* %OwlVarStub */, "",
     
    225269                 "The sepbar is the bar separating the top and bottom\n"
    226270                 "of the BarnOwl screen.  Any string specified here will\n"
    227                  "be displayed on the right of the sepbar\n"),
     271                 "be displayed on the right of the sepbar\n");
    228272
    229273  OWLVAR_BOOL( "zaway" /* %OwlVarStub */, 0,
    230                "turn zaway on or off", "" ),
     274               "turn zaway on or off", "" );
    231275
    232276  OWLVAR_STRING( "zaway_msg" /* %OwlVarStub */,
    233277                 OWL_DEFAULT_ZAWAYMSG,
    234                  "zaway msg for responding to zephyrs when away", "" ),
     278                 "zaway msg for responding to zephyrs when away", "" );
    235279
    236280  OWLVAR_STRING( "zaway_msg_default" /* %OwlVarStub */,
    237281                 OWL_DEFAULT_ZAWAYMSG,
    238                  "default zaway message", "" ),
     282                 "default zaway message", "" );
    239283
    240284  OWLVAR_BOOL_FULL( "aaway" /* %OwlVarStub */, 0,
    241285                    "Set AIM away status",
    242286                    "",
    243                     NULL, owl_variable_aaway_set, NULL),
     287                    NULL, owl_variable_aaway_set, NULL);
    244288
    245289  OWLVAR_STRING( "aaway_msg" /* %OwlVarStub */,
    246290                 OWL_DEFAULT_AAWAYMSG,
    247                  "AIM away msg for responding when away", "" ),
     291                 "AIM away msg for responding when away", "" );
    248292
    249293  OWLVAR_STRING( "aaway_msg_default" /* %OwlVarStub */,
    250294                 OWL_DEFAULT_AAWAYMSG,
    251                  "default AIM away message", "" ),
     295                 "default AIM away message", "" );
    252296
    253297  OWLVAR_STRING( "view_home" /* %OwlVarStub */, "all",
    254298                 "home view to switch to after 'X' and 'V'",
    255                  "SEE ALSO: view, filter\n" ),
     299                 "SEE ALSO: view, filter\n" );
    256300
    257301  OWLVAR_STRING( "alert_filter" /* %OwlVarStub */, "none",
    258302                 "filter on which to trigger alert actions",
    259                  "" ),
     303                 "" );
    260304
    261305  OWLVAR_STRING( "alert_action" /* %OwlVarStub */, "nop",
    262306                 "BarnOwl command to execute for alert actions",
    263                  "" ),
     307                 "" );
    264308
    265309  OWLVAR_STRING_FULL( "tty" /* %OwlVarStub */, "", "<string>", "tty name for zephyr location", "",
    266                       NULL, owl_variable_tty_set, NULL),
     310                      NULL, owl_variable_tty_set, NULL);
    267311
    268312  OWLVAR_STRING( "default_style" /* %OwlVarStub */, "default",
     
    275319                 "   perl     - legacy perl interface\n"
    276320                 "\nSEE ALSO: style, show styles, view -s <style>\n"
    277                  ),
     321                 );
    278322
    279323
     
    282326                 "This specifies the maximum number of columns for M-q to fill text\n"
    283327                 "to.  If set to 0, M-q will wrap to the width of the window, and\n"
    284                  "values less than 0 disable M-q entirely.\n"),
     328                 "values less than 0 disable M-q entirely.\n");
    285329
    286330  OWLVAR_INT(    "edit:maxwrapcols" /* %OwlVarStub:edit_maxwrapcols */, 70,
     
    291335                 "\n"
    292336                 "As a courtesy to recipients, it is recommended that outgoing\n"
    293                  "Zephyr messages be no wider than 70 columns.\n"),
     337                 "Zephyr messages be no wider than 70 columns.\n");
    294338
    295339  OWLVAR_INT( "aim_ignorelogin_timer" /* %OwlVarStub */, 15,
     
    298342              "AIM login before allowing the receipt of AIM login notifications.\n"
    299343              "By default this is set to 15.  If you would like to view login\n"
    300               "notifications of buddies as soon as you login, set it to 0 instead."),
     344              "notifications of buddies as soon as you login, set it to 0 instead.");
    301345
    302346             
     
    311355                   owl_variable_typewinsize_set,
    312356                   NULL /* use default for get */
    313                    ),
     357                   );
    314358
    315359  OWLVAR_INT( "typewindelta" /* %OwlVarStub */, 0,
     
    321365           "typewinsize to 1.\n\n"
    322366           "This works a lot better with a non-default scrollmode;\n"
    323            "try :set scrollmode pagedcenter.\n"),
     367           "try :set scrollmode pagedcenter.\n");
    324368
    325369  OWLVAR_ENUM( "scrollmode" /* %OwlVarStub */, OWL_SCROLLMODE_NORMAL,
     
    350394               "                 the screen will be paged up or down and\n"
    351395               "                 the cursor will be near the center.\n",
    352                "normal,top,neartop,center,paged,pagedcenter" ),
     396               "normal,top,neartop,center,paged,pagedcenter" );
    353397
    354398  OWLVAR_BOOL( "narrow-related" /* %OwlVarStub:narrow_related */, 1,
     
    358402               "for Zephyr, this controls whether to narrow to e.g. class-help or\n"
    359403               "class-help.d alone, or to related-class-help, which includes\n"
    360                "help, unhelp, help.d, etc.\n\nDefault is true (include unclasses, etc.).\n" ),
     404               "help, unhelp, help.d, etc.\n\nDefault is true (include unclasses, etc.).\n" );
    361405
    362406  OWLVAR_BOOL( "_followlast" /* %OwlVarStub */, 0,
     
    365409               "continue to follow the last message if this is set.\n"
    366410               "Note that this is currently risky as you might accidentally\n"
    367                "delete a message right as it came in.\n" ),
     411               "delete a message right as it came in.\n" );
    368412
    369413  OWLVAR_STRING_FULL( "default_exposure" /* %OwlVarStub */, "",
     
    374418                      "~/.zephyr.vars.\n"
    375419                      "See the description of exposure for the values this can be.",
    376                       NULL, owl_variable_default_exposure_set, owl_variable_default_exposure_get ),
     420                      NULL, owl_variable_default_exposure_set, owl_variable_default_exposure_get );
    377421
    378422  OWLVAR_STRING_FULL( "exposure" /* %OwlVarStub */, "",
     
    430474                      "                     personal subscriptions will be entered for the\n"
    431475                      "                     user.\n",
    432                       NULL, owl_variable_exposure_set, NULL /* use default for get */ ),
    433 
    434   /* This MUST be last... */
    435   { NULL, 0, NULL, 0, NULL, NULL, NULL, NULL,
    436     NULL, NULL, NULL, NULL, NULL, NULL }
    437 
    438   };
    439 
    440   int ret = owl_variable_dict_add_from_list(vd, variables_to_init);
    441   owl_variable *var;
    442   for (var = variables_to_init; var->name != NULL; var++)
    443     owl_variable_cleanup(var);
    444   return ret;
     476                      NULL, owl_variable_exposure_set, NULL /* use default for get */ );
    445477}
    446478
     
    452484/* commonly useful */
    453485
    454 int owl_variable_int_validate_gt0(const owl_variable *v, const void *newval)
    455 {
    456   if (newval == NULL) return(0);
    457   else if (*(const int*)newval < 1) return(0);
    458   else return (1);
    459 }
    460 
    461 int owl_variable_int_validate_positive(const owl_variable *v, const void *newval)
    462 {
    463   if (newval == NULL) return(0);
    464   else if (*(const int*)newval < 0) return(0);
    465   else return (1);
     486int owl_variable_int_validate_gt0(const owl_variable *v, int newval)
     487{
     488  return !(newval < 1);
     489}
     490
     491int owl_variable_int_validate_positive(const owl_variable *v, int newval)
     492{
     493  return !(newval < 0);
    466494}
    467495
    468496/* typewinsize */
    469 int owl_variable_typewinsize_set(owl_variable *v, const void *newval)
     497int owl_variable_typewinsize_set(owl_variable *v, int newval)
    470498{
    471499  int rv;
     
    476504
    477505/* debug (cache value in g->debug) */
    478 int owl_variable_debug_set(owl_variable *v, const void *newval)
    479 {
    480   if (newval && (*(const int*)newval == 1 || *(const int*)newval == 0)) {
    481     g.debug = *(const int*)newval;
     506int owl_variable_debug_set(owl_variable *v, bool newval)
     507{
     508  g.debug = newval;
     509  return owl_variable_bool_set_default(v, newval);
     510}
     511
     512/* When 'aaway' is changed, need to notify the AIM server */
     513int owl_variable_aaway_set(owl_variable *v, bool newval)
     514{
     515  if (newval) {
     516    owl_aim_set_awaymsg(owl_global_get_aaway_msg(&g));
     517  } else {
     518    owl_aim_set_awaymsg("");
    482519  }
    483520  return owl_variable_bool_set_default(v, newval);
    484521}
    485522
    486 /* When 'aaway' is changed, need to notify the AIM server */
    487 int owl_variable_aaway_set(owl_variable *v, const void *newval)
    488 {
    489   if (newval) {
    490     if (*(const int*)newval == 1) {
    491       owl_aim_set_awaymsg(owl_global_get_aaway_msg(&g));
    492     } else if (*(const int*)newval == 0) {
    493       owl_aim_set_awaymsg("");
    494     }
    495   }
    496   return owl_variable_bool_set_default(v, newval);
    497 }
    498 
    499 int owl_variable_colorztext_set(owl_variable *v, const void *newval)
     523int owl_variable_colorztext_set(owl_variable *v, bool newval)
    500524{
    501525  int ret = owl_variable_bool_set_default(v, newval);
     
    510534}
    511535
    512 int owl_variable_pseudologins_set(owl_variable *v, const void *newval)
     536int owl_variable_pseudologins_set(owl_variable *v, bool newval)
    513537{
    514538  static guint timer = 0;
    515539  if (newval) {
    516     if (*(const int*)newval == 1) {
    517       owl_function_zephyr_buddy_check(0);
    518       if (timer == 0) {
    519         timer = g_timeout_add_seconds(180, owl_zephyr_buddycheck_timer, NULL);
    520       }
    521     } else {
    522       if (timer != 0) {
    523         g_source_remove(timer);
    524         timer = 0;
    525       }
     540    owl_function_zephyr_buddy_check(0);
     541    if (timer == 0) {
     542      timer = g_timeout_add_seconds(180, owl_zephyr_buddycheck_timer, NULL);
     543    }
     544  } else {
     545    if (timer != 0) {
     546      g_source_remove(timer);
     547      timer = 0;
    526548    }
    527549  }
     
    531553/* note that changing the value of this will clobber
    532554 * any user setting of this */
    533 int owl_variable_disable_ctrl_d_set(owl_variable *v, const void *newval)
    534 {
    535   if (newval && !owl_context_is_startup(owl_global_get_context(&g))) {
    536     if (*(const int*)newval == 2) {
     555int owl_variable_disable_ctrl_d_set(owl_variable *v, int newval)
     556{
     557  if (!owl_context_is_startup(owl_global_get_context(&g))) {
     558    if (newval == 2) {
    537559      owl_function_command_norv("bindkey editmulti C-d command edit:delete-next-char");
    538     } else if (*(const int*)newval == 1) {
     560    } else if (newval == 1) {
    539561      owl_function_command_norv("bindkey editmulti C-d command edit:done-or-delete");
    540562    } else {
     
    542564    }
    543565  } 
    544   return owl_variable_int_set_default(v, newval); 
    545 }
    546 
    547 int owl_variable_tty_set(owl_variable *v, const void *newval)
     566  return owl_variable_int_set_default(v, newval);
     567}
     568
     569int owl_variable_tty_set(owl_variable *v, const char *newval)
    548570{
    549571  owl_zephyr_set_locationinfo(g_get_host_name(), newval);
    550   return(owl_variable_string_set_default(v, newval));
    551 }
    552 
    553 int owl_variable_default_exposure_set(owl_variable *v, const void *newval)
     572  return owl_variable_string_set_default(v, newval);
     573}
     574
     575int owl_variable_default_exposure_set(owl_variable *v, const char *newval)
    554576{
    555577  return owl_zephyr_set_default_exposure(newval);
    556578}
    557579
    558 const void *owl_variable_default_exposure_get(const owl_variable *v)
     580const char *owl_variable_default_exposure_get(const owl_variable *v)
    559581{
    560582  return owl_zephyr_get_default_exposure();
    561583}
    562584
    563 int owl_variable_exposure_set(owl_variable *v, const void *newval)
     585int owl_variable_exposure_set(owl_variable *v, const char *newval)
    564586{
    565587  int ret = owl_zephyr_set_exposure(newval);
     
    573595/**************************************************************************/
    574596
    575 int owl_variable_dict_setup(owl_vardict *vd) {
     597void owl_variable_dict_setup(owl_vardict *vd) {
    576598  owl_dict_create(vd);
    577   return owl_variable_add_defaults(vd);
    578 }
    579 
    580 int owl_variable_dict_add_from_list(owl_vardict *vd, owl_variable *variables_to_init)
    581 {
    582   owl_variable *var, *cur;
    583   for (var = variables_to_init; var->name != NULL; var++) {
    584     cur = g_new(owl_variable, 1);
    585     *cur = *var;
    586     /* strdup all the strings so we can delete them consistently. */
    587     cur->name = g_strdup(var->name);
    588     cur->summary = g_strdup(var->summary);
    589     cur->description = g_strdup(var->description);
    590     switch (cur->type) {
    591     case OWL_VARIABLE_OTHER:
    592       cur->set_fn(cur, cur->pval_default);
    593       break;
    594     case OWL_VARIABLE_STRING:
    595       if (!cur->validate_fn)
    596         cur->validate_fn = owl_variable_string_validate_default;
    597       if (!cur->set_fn)
    598         cur->set_fn = owl_variable_string_set_default;
    599       if (!cur->set_fromstring_fn)
    600         cur->set_fromstring_fn = owl_variable_string_set_fromstring_default;
    601       if (!cur->get_fn)
    602         cur->get_fn = owl_variable_get_default;
    603       if (!cur->get_tostring_fn)
    604         cur->get_tostring_fn = owl_variable_string_get_tostring_default;     
    605       if (!cur->delete_fn)
    606         cur->delete_fn = owl_variable_delete_default;
    607       cur->pval_default = g_strdup(var->pval_default);
    608       cur->set_fn(cur, cur->pval_default);
    609       break;
    610     case OWL_VARIABLE_BOOL:
    611       if (!cur->validate_fn)
    612         cur->validate_fn = owl_variable_bool_validate_default;
    613       if (!cur->set_fn)
    614         cur->set_fn = owl_variable_bool_set_default;
    615       if (!cur->set_fromstring_fn)
    616         cur->set_fromstring_fn = owl_variable_bool_set_fromstring_default;
    617       if (!cur->get_fn)
    618         cur->get_fn = owl_variable_get_default;
    619       if (!cur->get_tostring_fn)
    620         cur->get_tostring_fn = owl_variable_bool_get_tostring_default;     
    621       if (!cur->delete_fn)
    622         cur->delete_fn = owl_variable_delete_default;
    623       cur->val = g_new(int, 1);
    624       cur->set_fn(cur, &cur->ival_default);
    625       break;
    626     case OWL_VARIABLE_INT:
    627       if (!cur->validate_fn)
    628         cur->validate_fn = owl_variable_int_validate_default;
    629       if (!cur->set_fn)
    630         cur->set_fn = owl_variable_int_set_default;
    631       if (!cur->set_fromstring_fn)
    632         cur->set_fromstring_fn = owl_variable_int_set_fromstring_default;
    633       if (!cur->get_fn)
    634         cur->get_fn = owl_variable_get_default;
    635       if (!cur->get_tostring_fn)
    636         cur->get_tostring_fn = owl_variable_int_get_tostring_default;     
    637       if (!cur->delete_fn)
    638         cur->delete_fn = owl_variable_delete_default;
    639       cur->val = g_new(int, 1);
    640       cur->set_fn(cur, &cur->ival_default);
    641       break;
    642     default:
    643       fprintf(stderr, "owl_variable_setup: invalid variable type\n");
    644       return(-2);
    645     }
    646     owl_dict_insert_element(vd, cur->name, cur, NULL);
    647   }
    648   return 0;
     599  owl_variable_add_defaults(vd);
     600}
     601
     602CALLER_OWN GClosure *owl_variable_make_closure(owl_variable *v,
     603                                               GCallback fn,
     604                                               GClosureMarshal marshal) {
     605  GClosure *closure = g_cclosure_new_swap(fn, v, NULL);
     606  g_closure_set_marshal(closure,marshal);
     607  g_closure_ref(closure);
     608  g_closure_sink(closure);
     609  return closure;
    649610}
    650611
     
    654615}
    655616
    656 CALLER_OWN owl_variable *owl_variable_newvar(const char *name, const char *summary, const char *description)
    657 {
    658   owl_variable * var = g_new0(owl_variable, 1);
     617static owl_variable *owl_variable_newvar(int type, const char *name, const char *summary, const char *description, const char *validsettings) {
     618  owl_variable *var = g_new0(owl_variable, 1);
     619  var->type = type;
    659620  var->name = g_strdup(name);
    660621  var->summary = g_strdup(summary);
    661622  var->description = g_strdup(description);
     623  var->validsettings = g_strdup(validsettings);
    662624  return var;
    663625}
    664626
    665 void owl_variable_update(owl_variable *var, const char *summary, const char *desc) {
    666   g_free(var->summary);
    667   var->summary = g_strdup(summary);
    668   g_free(var->description);
    669   var->description = g_strdup(desc);
    670 }
    671 
    672 void owl_variable_dict_newvar_string(owl_vardict *vd, const char *name, const char *summ, const char *desc, const char *initval)
    673 {
    674   owl_variable *old = owl_variable_get_var(vd, name);
    675   if (old && owl_variable_get_type(old) == OWL_VARIABLE_STRING) {
    676     owl_variable_update(old, summ, desc);
    677     g_free(old->pval_default);
    678     old->pval_default = g_strdup(initval);
    679   } else {
    680     owl_variable * var = owl_variable_newvar(name, summ, desc);
    681     var->type = OWL_VARIABLE_STRING;
    682     var->validsettings = "<string>";
    683     var->pval_default = g_strdup(initval);
    684     var->set_fn = owl_variable_string_set_default;
    685     var->set_fromstring_fn = owl_variable_string_set_fromstring_default;
    686     var->get_fn = owl_variable_get_default;
    687     var->get_tostring_fn = owl_variable_string_get_tostring_default;
    688     var->delete_fn = owl_variable_delete_default;
    689     var->set_fn(var, initval);
    690     owl_variable_dict_add_variable(vd, var);
    691   }
    692 }
    693 
    694 void owl_variable_dict_newvar_int(owl_vardict *vd, const char *name, const char *summ, const char *desc, int initval)
    695 {
    696   owl_variable *old = owl_variable_get_var(vd, name);
    697   if (old && owl_variable_get_type(old) == OWL_VARIABLE_INT) {
    698     owl_variable_update(old, summ, desc);
    699     old->ival_default = initval;
    700   } else {
    701     owl_variable * var = owl_variable_newvar(name, summ, desc);
    702     var->type = OWL_VARIABLE_INT;
    703     var->validsettings = "<int>";
    704     var->ival_default = initval;
    705     var->validate_fn = owl_variable_int_validate_default;
    706     var->set_fn = owl_variable_int_set_default;
    707     var->set_fromstring_fn = owl_variable_int_set_fromstring_default;
    708     var->get_fn = owl_variable_get_default;
    709     var->get_tostring_fn = owl_variable_int_get_tostring_default;
    710     var->delete_fn = owl_variable_delete_default;
    711     var->val = g_new(int, 1);
    712     var->set_fn(var, &initval);
    713     owl_variable_dict_add_variable(vd, var);
    714   }
    715 }
    716 
    717 void owl_variable_dict_newvar_bool(owl_vardict *vd, const char *name, const char *summ, const char *desc, int initval)
    718 {
    719   owl_variable *old = owl_variable_get_var(vd, name);
    720   if (old && owl_variable_get_type(old) == OWL_VARIABLE_BOOL) {
    721     owl_variable_update(old, summ, desc);
    722     old->ival_default = initval;
    723   } else {
    724     owl_variable * var = owl_variable_newvar(name, summ, desc);
    725     var->type = OWL_VARIABLE_BOOL;
    726     var->validsettings = "on,off";
    727     var->ival_default = initval;
    728     var->validate_fn = owl_variable_bool_validate_default;
    729     var->set_fn = owl_variable_bool_set_default;
    730     var->set_fromstring_fn = owl_variable_bool_set_fromstring_default;
    731     var->get_fn = owl_variable_get_default;
    732     var->get_tostring_fn = owl_variable_bool_get_tostring_default;
    733     var->delete_fn = owl_variable_delete_default;
    734     var->val = g_new(int, 1);
    735     var->set_fn(var, &initval);
    736     owl_variable_dict_add_variable(vd, var);
    737   }
     627static void owl_variable_dict_newvar_int_full(owl_vardict *vd, const char *name, int default_val, const char *summary, const char *description, const char *validsettings, validate_int_t validate_fn, set_int_t set_fn, get_int_t get_fn)
     628{
     629  owl_variable *var = owl_variable_newvar(OWL_VARIABLE_INT, name, summary,
     630                                          description, validsettings);
     631  var->takes_on_off = false;
     632  var->get_fn = G_CALLBACK(get_fn ? get_fn : owl_variable_int_get_default);
     633  var->set_fn = G_CALLBACK(set_fn ? set_fn : owl_variable_int_set_default);
     634  var->validate_fn = G_CALLBACK(validate_fn ? validate_fn : owl_variable_int_validate_default);
     635
     636  var->get_tostring_fn = owl_variable_make_closure(
     637      var, G_CALLBACK(owl_variable_int_get_tostring_default),
     638      g_cclosure_user_marshal_STRING__VOID);
     639  var->set_fromstring_fn = owl_variable_make_closure(
     640      var, G_CALLBACK(owl_variable_int_set_fromstring_default),
     641      g_cclosure_user_marshal_INT__STRING);
     642
     643  g_value_init(&var->val, G_TYPE_INT);
     644  owl_variable_set_int(var, default_val);
     645
     646  var->default_str = owl_variable_get_tostring(var);
     647  owl_variable_dict_add_variable(vd, var);
     648}
     649
     650void owl_variable_dict_newvar_int(owl_vardict *vd, const char *name, int default_val, const char *summary, const char *description) {
     651  owl_variable_dict_newvar_int_full(vd, name, default_val, summary, description,
     652                                    "<int>", NULL, NULL, NULL);
     653}
     654
     655static void owl_variable_dict_newvar_bool_full(owl_vardict *vd, const char *name, bool default_val, const char *summary, const char *description, validate_bool_t validate_fn, set_bool_t set_fn, get_bool_t get_fn)
     656{
     657  owl_variable *var = owl_variable_newvar(OWL_VARIABLE_BOOL, name, summary,
     658                                          description, "on,off");
     659  var->takes_on_off = true;
     660  var->get_fn = G_CALLBACK(get_fn ? get_fn : owl_variable_bool_get_default);
     661  var->set_fn = G_CALLBACK(set_fn ? set_fn : owl_variable_bool_set_default);
     662  var->validate_fn = G_CALLBACK(validate_fn ? validate_fn : owl_variable_bool_validate_default);
     663
     664  var->get_tostring_fn = owl_variable_make_closure(
     665      var, G_CALLBACK(owl_variable_bool_get_tostring_default),
     666      g_cclosure_user_marshal_STRING__VOID);
     667  var->set_fromstring_fn = owl_variable_make_closure(
     668      var, G_CALLBACK(owl_variable_bool_set_fromstring_default),
     669      g_cclosure_user_marshal_INT__STRING);
     670
     671  g_value_init(&var->val, G_TYPE_BOOLEAN);
     672  owl_variable_set_bool(var, default_val);
     673
     674  var->default_str = owl_variable_get_tostring(var);
     675  owl_variable_dict_add_variable(vd, var);
     676}
     677
     678void owl_variable_dict_newvar_bool(owl_vardict *vd, const char *name, bool default_val, const char *summary, const char *description) {
     679  owl_variable_dict_newvar_bool_full(vd, name, default_val, summary, description,
     680                                     NULL, NULL, NULL);
     681}
     682
     683static void owl_variable_dict_newvar_string_full(owl_vardict *vd, const char *name, const char *default_val, const char *summary, const char *description, const char *validsettings, validate_string_t validate_fn, set_string_t set_fn, get_string_t get_fn)
     684{
     685  owl_variable *var = owl_variable_newvar(OWL_VARIABLE_STRING, name, summary,
     686                                          description, validsettings);
     687  var->takes_on_off = false;
     688  var->get_fn = G_CALLBACK(get_fn ? get_fn : owl_variable_string_get_default);
     689  var->set_fn = G_CALLBACK(set_fn ? set_fn : owl_variable_string_set_default);
     690  var->validate_fn = G_CALLBACK(validate_fn ? validate_fn : owl_variable_string_validate_default);
     691
     692  var->get_tostring_fn = owl_variable_make_closure(
     693      var, G_CALLBACK(owl_variable_string_get_tostring_default),
     694      g_cclosure_user_marshal_STRING__VOID);
     695  var->set_fromstring_fn = owl_variable_make_closure(
     696      var, G_CALLBACK(owl_variable_string_set_fromstring_default),
     697      g_cclosure_user_marshal_INT__STRING);
     698
     699  g_value_init(&var->val, G_TYPE_STRING);
     700  owl_variable_set_string(var, default_val);
     701
     702  var->default_str = owl_variable_get_tostring(var);
     703  owl_variable_dict_add_variable(vd, var);
     704}
     705
     706void owl_variable_dict_newvar_string(owl_vardict *vd, const char *name, const char *default_val, const char *summary, const char *description) {
     707  owl_variable_dict_newvar_string_full(vd, name, default_val, summary, description,
     708                                       "<string>", NULL, NULL, NULL);
     709}
     710
     711void owl_variable_dict_newvar_path(owl_vardict *vd, const char *name, const char *default_val, const char *summary, const char *description) {
     712  owl_variable_dict_newvar_string_full(vd, name, default_val, summary, description,
     713                                       "<path>", NULL, NULL, NULL);
     714}
     715
     716static void owl_variable_dict_newvar_enum_full(owl_vardict *vd, const char *name, int default_val, const char *summary, const char *description, const char *validsettings, validate_int_t validate_fn, set_int_t set_fn, get_int_t get_fn)
     717{
     718  owl_variable *var = owl_variable_newvar(OWL_VARIABLE_INT, name, summary,
     719                                          description, validsettings);
     720  var->takes_on_off = false;
     721  var->get_fn = G_CALLBACK(get_fn ? get_fn : owl_variable_int_get_default);
     722  var->set_fn = G_CALLBACK(set_fn ? set_fn : owl_variable_int_set_default);
     723  var->validate_fn = G_CALLBACK(validate_fn ? validate_fn : owl_variable_enum_validate);
     724
     725  var->get_tostring_fn = owl_variable_make_closure(
     726      var, G_CALLBACK(owl_variable_enum_get_tostring),
     727      g_cclosure_user_marshal_STRING__VOID);
     728  var->set_fromstring_fn = owl_variable_make_closure(
     729      var, G_CALLBACK(owl_variable_enum_set_fromstring),
     730      g_cclosure_user_marshal_INT__STRING);
     731
     732  g_value_init(&var->val, G_TYPE_INT);
     733  owl_variable_set_int(var, default_val);
     734
     735  var->default_str = owl_variable_get_tostring(var);
     736  owl_variable_dict_add_variable(vd, var);
     737}
     738
     739void owl_variable_dict_newvar_enum(owl_vardict *vd, const char *name, int default_val, const char *summary, const char *description, const char *validset) {
     740  owl_variable_dict_newvar_enum_full(vd, name, default_val, summary, description,
     741                                     validset, NULL, NULL, NULL);
     742}
     743
     744void owl_variable_dict_newvar_other(owl_vardict *vd, const char *name, const char *summary, const char *description, const char *validsettings, bool takes_on_off, GClosure *get_tostring_fn, GClosure *set_fromstring_fn)
     745{
     746  owl_variable *var = owl_variable_newvar(OWL_VARIABLE_OTHER, name, summary,
     747                                          description, validsettings);
     748  var->takes_on_off = takes_on_off;
     749
     750  var->get_tostring_fn = g_closure_ref(get_tostring_fn);
     751  g_closure_sink(get_tostring_fn);
     752
     753  var->set_fromstring_fn = g_closure_ref(set_fromstring_fn);
     754  g_closure_sink(set_fromstring_fn);
     755
     756  var->default_str = owl_variable_get_tostring(var);
     757
     758  /* Note: this'll overwrite any existing variable of that name, even a C one,
     759     but it's consistent with previous behavior and commands. */
     760  owl_variable_dict_add_variable(vd, var);
    738761}
    739762
     
    747770}
    748771
    749 void owl_variable_cleanup(owl_variable *v)
    750 {
    751   if (v->delete_fn) v->delete_fn(v);
     772void owl_variable_delete(owl_variable *v)
     773{
    752774  g_free(v->name);
    753775  g_free(v->summary);
    754776  g_free(v->description);
    755   if (v->type == OWL_VARIABLE_STRING)
    756     g_free(v->pval_default);
    757 }
    758 
    759 void owl_variable_delete(owl_variable *v)
    760 {
    761   owl_variable_cleanup(v);
     777  g_free(v->default_str);
     778  g_free(v->validsettings);
     779  g_value_unset(&(v->val));
     780  g_closure_unref(v->get_tostring_fn);
     781  g_closure_unref(v->set_fromstring_fn);
     782
    762783  g_free(v);
    763784}
     
    785806  return v->type;
    786807}
    787 
    788 /* functions for getting and setting variable values */
    789808
    790809/* returns 0 on success, prints a status msg if msg is true */
    791810int owl_variable_set_fromstring(owl_variable *v, const char *value, int msg) {
    792811  char *tostring;
    793   if (!v->set_fromstring_fn) {
    794     if (msg) owl_function_error("Variable %s is read-only", owl_variable_get_name(v));
    795     return -1;   
    796   }
    797   if (0 != v->set_fromstring_fn(v, value)) {
     812  GValue values[] = {G_VALUE_INIT, G_VALUE_INIT};
     813  GValue return_box = G_VALUE_INIT;
     814  int set_successfully;
     815
     816  g_value_init(&values[0], G_TYPE_POINTER);
     817  g_value_set_pointer(&values[0], NULL);
     818  g_value_init(&values[1], G_TYPE_STRING);
     819  g_value_set_static_string(&values[1], value);
     820  g_value_init(&return_box, G_TYPE_INT);
     821  g_closure_invoke(v->set_fromstring_fn, &return_box, 2, values, NULL);
     822
     823  set_successfully = g_value_get_int(&return_box);
     824  if (0 != set_successfully) {
    798825    if (msg) owl_function_error("Unable to set %s (must be %s)", owl_variable_get_name(v),
    799826                                owl_variable_get_validsettings(v));
    800     return -1;
     827  } else if (msg) {
     828    tostring = owl_variable_get_tostring(v);
     829    if (tostring) {
     830      owl_function_makemsg("%s = '%s'", owl_variable_get_name(v), tostring);
     831    } else {
     832      owl_function_makemsg("%s = <null>", owl_variable_get_name(v));
     833    }
     834    g_free(tostring);
    801835  }
    802   if (msg) {
    803     tostring = v->get_tostring_fn(v, v->get_fn(v));
    804     if (tostring)
    805       owl_function_makemsg("%s = '%s'", owl_variable_get_name(v), tostring);
    806     else
    807       owl_function_makemsg("%s = <null>", owl_variable_get_name(v));
    808     g_free(tostring);
    809   }   
    810   return 0;
     836
     837  g_value_unset(&return_box);
     838  g_value_unset(&values[1]);
     839  g_value_unset(&values[0]);
     840  return set_successfully;
    811841}
    812842 
    813843int owl_variable_set_string(owl_variable *v, const char *newval)
    814844{
    815   if (v->type != OWL_VARIABLE_STRING) return -1;
    816   return v->set_fn(v, newval);
    817 }
    818  
     845  g_return_val_if_fail(v->type == OWL_VARIABLE_STRING, -1);
     846
     847  set_string_t cb = (set_string_t) v->set_fn;
     848  return cb(v, newval);
     849}
     850
    819851int owl_variable_set_int(owl_variable *v, int newval)
    820852{
    821   if (v->type != OWL_VARIABLE_INT && v->type != OWL_VARIABLE_BOOL) return -1;
    822   return v->set_fn(v, &newval);
    823 }
    824  
     853  g_return_val_if_fail(v->type == OWL_VARIABLE_INT, -1);
     854
     855  set_int_t cb = (set_int_t) v->set_fn;
     856  return cb(v, newval);
     857}
     858
     859int owl_variable_set_bool(owl_variable *v, bool newval) {
     860  g_return_val_if_fail(v->type == OWL_VARIABLE_BOOL, -1);
     861
     862  set_bool_t cb = (set_bool_t) v->set_fn;
     863  return cb(v, newval);
     864}
     865
    825866int owl_variable_set_bool_on(owl_variable *v)
    826867{
    827868  if (v->type != OWL_VARIABLE_BOOL) return -1;
    828   return owl_variable_set_int(v, true);
     869  return owl_variable_set_bool(v, true);
    829870}
    830871
     
    832873{
    833874  if (v->type != OWL_VARIABLE_BOOL) return -1;
    834   return owl_variable_set_int(v, false);
     875  return owl_variable_set_bool(v, false);
    835876}
    836877
    837878CALLER_OWN char *owl_variable_get_tostring(const owl_variable *v)
    838879{
    839   return v->get_tostring_fn(v, v->get_fn(v));
    840 }
    841 
    842 CALLER_OWN char *owl_variable_get_default_tostring(const owl_variable *v)
    843 {
    844   if (v->type == OWL_VARIABLE_INT || v->type == OWL_VARIABLE_BOOL) {
    845     return v->get_tostring_fn(v, &(v->ival_default));
    846   } else {
    847     return v->get_tostring_fn(v, v->pval_default);
    848   }
     880  GValue instance = G_VALUE_INIT;
     881  GValue tostring_box = G_VALUE_INIT;
     882  char *ret = NULL;
     883
     884  g_value_init(&instance, G_TYPE_POINTER);
     885  g_value_set_pointer(&instance, NULL);
     886  g_value_init(&tostring_box, G_TYPE_STRING);
     887  g_closure_invoke(v->get_tostring_fn, &tostring_box, 1, &instance, NULL);
     888
     889  ret = g_value_dup_string(&tostring_box);
     890
     891  g_value_unset(&tostring_box);
     892  g_value_unset(&instance);
     893  return ret;
     894}
     895
     896const char *owl_variable_get_default_tostring(const owl_variable *v)
     897{
     898  return v->default_str;
    849899}
    850900
     
    854904}
    855905
    856 /* returns a reference */
    857 const void *owl_variable_get(const owl_variable *v)
    858 {
    859   return v->get_fn(v);
    860 }
    861 
    862906const char *owl_variable_get_string(const owl_variable *v)
    863907{
    864   if (owl_variable_get_type(v) != OWL_VARIABLE_STRING) {
    865     owl_function_error("Variable '%s' is not a string.", owl_variable_get_name(v));
    866     return NULL;
    867   }
    868   return owl_variable_get(v);
    869 }
    870 
    871 /* returns a reference */
    872 const void *owl_variable_get_other(const owl_variable *v)
    873 {
    874   if (owl_variable_get_type(v) != OWL_VARIABLE_OTHER) {
    875     owl_function_error("Variable '%s' is not type other.", owl_variable_get_name(v));
    876     return NULL;
    877   }
    878   return owl_variable_get(v);
     908  g_return_val_if_fail(v->type == OWL_VARIABLE_STRING, NULL);
     909
     910  get_string_t cb = (get_string_t) v->get_fn;
     911  return cb(v);
    879912}
    880913
    881914int owl_variable_get_int(const owl_variable *v)
    882915{
    883   if (owl_variable_get_type(v) != OWL_VARIABLE_INT) {
    884     owl_function_error("Variable '%s' is an int.", owl_variable_get_name(v));
    885     return -1;
    886   }
    887   const int *pi = owl_variable_get(v);
    888   if (!pi) return -1;
    889   return *pi;
    890 }
    891 
    892 int owl_variable_get_bool(const owl_variable *v)
    893 {
    894   if (owl_variable_get_type(v) != OWL_VARIABLE_BOOL) {
    895     owl_function_error("Variable '%s' is a boolean.", owl_variable_get_name(v));
    896     return -1;
    897   }
    898   const int *pi = owl_variable_get(v);
    899   if (!pi) return -1;
    900   return *pi;
     916  g_return_val_if_fail(v->type == OWL_VARIABLE_INT, 0);
     917
     918  get_int_t cb = (get_int_t) v->get_fn;
     919  return cb(v);
     920}
     921
     922bool owl_variable_get_bool(const owl_variable *v)
     923{
     924  g_return_val_if_fail(v->type == OWL_VARIABLE_BOOL, FALSE);
     925
     926  get_bool_t cb = (get_bool_t) v->get_fn;
     927  return cb(v);
    901928}
    902929
    903930void owl_variable_describe(const owl_variable *v, owl_fmtext *fm)
    904931{
    905   char *tostring = owl_variable_get_default_tostring(v);
     932  const char *default_str = owl_variable_get_default_tostring(v);
    906933  char *default_buf;
    907934
    908   if (tostring)
    909     default_buf = g_strdup_printf("'%s'", tostring);
     935  if (default_str)
     936    default_buf = g_strdup_printf("'%s'", default_str);
    910937  else
    911938    default_buf = g_strdup("<null>");
     
    914941                            owl_variable_get_summary(v), default_buf);
    915942  g_free(default_buf);
    916   g_free(tostring);
    917943}
    918944
    919945void owl_variable_get_help(const owl_variable *v, owl_fmtext *fm) {
    920946  char *tostring;
     947  const char *default_str;
    921948
    922949  owl_fmtext_append_bold(fm, "OWL VARIABLE\n\n");
     
    933960  owl_fmtext_append_normal(fm, "\n\n");
    934961
    935 
    936   tostring = owl_variable_get_default_tostring(v);
     962  default_str = owl_variable_get_default_tostring(v);
    937963  owl_fmtext_append_normal(fm, "Default:        ");
    938   owl_fmtext_append_normal(fm, (tostring ? tostring : "<null>"));
     964  owl_fmtext_append_normal(fm, (default_str ? default_str : "<null>"));
    939965  owl_fmtext_append_normal(fm, "\n\n");
    940966
     
    948974    owl_fmtext_append_normal(fm, "\n\n");
    949975  }
    950   g_free(tostring);
    951976}
    952977
     
    960985/* default common functions */
    961986
    962 const void *owl_variable_get_default(const owl_variable *v) {
    963   return v->val;
    964 }
    965 
    966 void owl_variable_delete_default(owl_variable *v)
    967 {
    968   g_free(v->val);
     987const char *owl_variable_string_get_default(const owl_variable *v) {
     988  return g_value_get_string(&(v->val));
     989}
     990
     991int owl_variable_int_get_default(const owl_variable *v) {
     992  return g_value_get_int(&(v->val));
     993}
     994
     995bool owl_variable_bool_get_default(const owl_variable *v) {
     996  return g_value_get_boolean(&(v->val));
    969997}
    970998
    971999/* default functions for booleans */
    9721000
    973 int owl_variable_bool_validate_default(const owl_variable *v, const void *newval) {
    974   if (newval == NULL) return(0);
    975   else if (*(const int*)newval==1 || *(const int*)newval==0) return(1);
    976   else return (0);
    977 }
    978 
    979 int owl_variable_bool_set_default(owl_variable *v, const void *newval) {
    980   if (v->validate_fn) {
    981     if (!v->validate_fn(v, newval)) return(-1);
     1001int owl_variable_bool_validate_default(const owl_variable *v, bool newval) {
     1002  return (newval == 1) || (newval == 0);
     1003}
     1004
     1005int owl_variable_bool_set_default(owl_variable *v, bool newval) {
     1006  if (!((validate_bool_t)v->validate_fn)(v, newval))
     1007    return -1;
     1008
     1009  g_value_set_boolean(&(v->val), newval);
     1010  return(0);
     1011}
     1012
     1013int owl_variable_bool_set_fromstring_default(owl_variable *v, const char *newval, void *dummy) {
     1014  bool i;
     1015  if (!strcmp(newval, "on")) {
     1016    i = true;
     1017  } else if (!strcmp(newval, "off")) {
     1018    i = false;
     1019  } else {
     1020    return(-1);
    9821021  }
    983   *(int*)v->val = *(const int*)newval;
    984   return(0);
    985 }
    986 
    987 int owl_variable_bool_set_fromstring_default(owl_variable *v, const char *newval) {
    988   int i;
    989   if (!strcmp(newval, "on")) i=1;
    990   else if (!strcmp(newval, "off")) i=0;
    991   else return(-1);
    992   return (v->set_fn(v, &i));
    993 }
    994 
    995 CALLER_OWN char *owl_variable_bool_get_tostring_default(const owl_variable *v, const void *val)
    996 {
    997   if (val == NULL) {
    998     return NULL;
    999   } else if (*(const int*)val == 0) {
     1022
     1023  return owl_variable_set_bool(v, i);
     1024}
     1025
     1026CALLER_OWN char *owl_variable_bool_get_tostring_default(const owl_variable *v, void *dummy)
     1027{
     1028  bool val = owl_variable_get_bool(v);
     1029  if (val == 0) {
    10001030    return g_strdup("off");
    1001   } else if (*(const int*)val == 1) {
     1031  } else if (val == 1) {
    10021032    return g_strdup("on");
    10031033  } else {
     
    10081038/* default functions for integers */
    10091039
    1010 int owl_variable_int_validate_default(const owl_variable *v, const void *newval) {
    1011   if (newval == NULL) return(0);
    1012   else return (1);
    1013 }
    1014 
    1015 int owl_variable_int_set_default(owl_variable *v, const void *newval) {
    1016   if (v->validate_fn) {
    1017     if (!v->validate_fn(v, newval)) return(-1);
    1018   }
    1019   *(int*)v->val = *(const int*)newval;
     1040int owl_variable_int_validate_default(const owl_variable *v, int newval)
     1041{
     1042  return (1);
     1043}
     1044
     1045int owl_variable_int_set_default(owl_variable *v, int newval) {
     1046  if (!((validate_int_t)v->validate_fn)(v, newval))
     1047    return -1;
     1048
     1049  g_value_set_int(&(v->val), newval);
    10201050  return(0);
    10211051}
    10221052
    1023 int owl_variable_int_set_fromstring_default(owl_variable *v, const char *newval) {
     1053int owl_variable_int_set_fromstring_default(owl_variable *v, const char *newval, void *dummy) {
    10241054  int i;
    10251055  char *ep;
    10261056  i = strtol(newval, &ep, 10);
    10271057  if (*ep || ep==newval) return(-1);
    1028   return (v->set_fn(v, &i));
    1029 }
    1030 
    1031 CALLER_OWN char *owl_variable_int_get_tostring_default(const owl_variable *v, const void *val)
    1032 {
    1033   if (val == NULL) {
    1034     return NULL;
    1035   } else {
    1036     return g_strdup_printf("%d", *(const int*)val);
    1037   }
     1058  return owl_variable_set_int(v, i);
     1059}
     1060
     1061CALLER_OWN char *owl_variable_int_get_tostring_default(const owl_variable *v, void *dummy)
     1062{
     1063  return g_strdup_printf("%d", owl_variable_get_int(v));
    10381064}
    10391065
    10401066/* default functions for enums (a variant of integers) */
    10411067
    1042 int owl_variable_enum_validate(const owl_variable *v, const void *newval) { 
     1068int owl_variable_enum_validate(const owl_variable *v, int newval) {
    10431069  char **enums;
    10441070  int nenums, val;
    1045   if (newval == NULL) return(0);
    10461071  enums = g_strsplit_set(v->validsettings, ",", 0);
    10471072  nenums = g_strv_length(enums);
    10481073  g_strfreev(enums);
    1049   val = *(const int*)newval;
     1074  val = newval;
    10501075  if (val < 0 || val >= nenums) {
    10511076    return(0);
     
    10541079}
    10551080
    1056 int owl_variable_enum_set_fromstring(owl_variable *v, const char *newval) {
     1081int owl_variable_enum_set_fromstring(owl_variable *v, const char *newval, void *dummy) {
    10571082  char **enums;
    10581083  int i, val=-1;
     
    10661091  g_strfreev(enums);
    10671092  if (val == -1) return(-1);
    1068   return (v->set_fn(v, &val));
    1069 }
    1070 
    1071 CALLER_OWN char *owl_variable_enum_get_tostring(const owl_variable *v, const void *val)
     1093  return owl_variable_set_int(v, val);
     1094}
     1095
     1096CALLER_OWN char *owl_variable_enum_get_tostring(const owl_variable *v, void *dummy)
    10721097{
    10731098  char **enums;
     
    10751100  char *tostring;
    10761101
    1077   if (val == NULL) {
    1078     return NULL;
    1079   }
    10801102  enums = g_strsplit_set(v->validsettings, ",", 0);
    10811103  nenums = g_strv_length(enums);
    1082   i = *(const int*)val;
     1104  i = owl_variable_get_int(v);
    10831105  if (i<0 || i>=nenums) {
    10841106    g_strfreev(enums);
     
    10921114/* default functions for stringeans */
    10931115
    1094 int owl_variable_string_validate_default(const struct _owl_variable *v, const void *newval) {
     1116int owl_variable_string_validate_default(const owl_variable *v, const char *newval) {
    10951117  if (newval == NULL) return(0);
    10961118  else return (1);
    10971119}
    10981120
    1099 int owl_variable_string_set_default(owl_variable *v, const void *newval) {
    1100   if (v->validate_fn) {
    1101     if (!v->validate_fn(v, newval)) return(-1);
    1102   }
    1103   g_free(v->val);
    1104   v->val = g_strdup(newval);
     1121int owl_variable_string_set_default(owl_variable *v, const char *newval) {
     1122  if (!((validate_string_t)v->validate_fn)(v, newval))
     1123    return -1;
     1124
     1125  g_value_set_string(&(v->val), newval);
    11051126  return(0);
    11061127}
    11071128
    1108 int owl_variable_string_set_fromstring_default(owl_variable *v, const char *newval) {
    1109   return (v->set_fn(v, newval));
    1110 }
    1111 
    1112 CALLER_OWN char *owl_variable_string_get_tostring_default(const owl_variable *v, const void *val)
    1113 {
    1114   return g_strdup((const char*)val);
    1115 }
    1116 
     1129int owl_variable_string_set_fromstring_default(owl_variable *v, const char *newval, void *dummy)
     1130{
     1131  return owl_variable_set_string(v, newval);
     1132}
     1133
     1134CALLER_OWN char *owl_variable_string_get_tostring_default(const owl_variable *v, void *dummy)
     1135{
     1136  return g_strdup(owl_variable_get_string(v));
     1137}
     1138
  • zephyr.c

    r9b3167b rbbe7d4a  
    291291  struct stat statbuff;
    292292
    293   subs = g_new(ZSubscription_t, subSize);
    294293  subsfile = owl_zephyr_dotfile(".zephyr.subs", filename);
    295294
     
    307306  if (!file)
    308307    return -1;
     308
     309  subs = g_new(ZSubscription_t, subSize);
    309310  while (owl_getline(&buffer, file)) {
    310311    if (buffer[0] == '#' || buffer[0] == '\n')
Note: See TracChangeset for help on using the changeset viewer.