Changeset 06e04a9


Ignore:
Timestamp:
Feb 19, 2013, 8:28:55 PM (5 years ago)
Author:
David Benjamin <davidben@mit.edu>
Branches:
master
Children:
353719a
Parents:
6a20996
git-author:
Adam Glasgall <adam@crossproduct.net> (07/20/11 00:04:42)
git-committer:
David Benjamin <davidben@mit.edu> (02/19/13 20:28:55)
Message:
perlvariables - iteration N

Later commits reworked a lot of this, but the use of GValue over void*
was kept.
Files:
4 added
7 edited

Legend:

Unmodified
Added
Removed
  • Makefile.am

    rc266281 r06e04a9  
    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 gmarshal_funcs.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
  • 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.c

    r4d9e311c r06e04a9  
    478478  char **argv_copy;
    479479  char *perlout, *perlerr;
     480  const char *dlerr;
    480481  const owl_style *s;
    481482  const char *dir;
     
    554555  }
    555556
     557  dlerr = owl_closure_init();
     558  if(dlerr) {
     559    endwin();
     560    fprintf(stderr, "Error binding gtk2-perl functions from C: %s\n",dlerr);
     561    fflush(stderr);
     562    fprintf(stdout, "Error binding gtk2-perl functions from C: %s\n",dlerr);
     563    fflush(stdout);
     564    exit(1);
     565  }
     566 
    556567  owl_global_complete_setup(&g);
    557568
  • owl.h

    rc42a8d1 r06e04a9  
    235235  char *name;
    236236  int   type;  /* OWL_VARIABLE_* */
     237  GValue gval_default;
     238  const char *validsettings;    /* documentation of valid settings */
     239  char *summary;                /* summary of usage */
     240  char *description;            /* detailed description */
     241  GValue val;                    /* current value */
     242  GClosure *validate_fn;
     243                                /* returns 1 if newval is valid */
     244  GClosure *set_fn;
     245                                /* sets the variable to a value
     246                                 * of the appropriate type.
     247                                 * unless documented, this
     248                                 * should make a copy.
     249                                 * returns 0 on success. */
     250  GClosure *set_fromstring_fn;
     251                                /* sets the variable to a value
     252                                 * of the appropriate type.
     253                                 * unless documented, this
     254                                 * should make a copy.
     255                                 * returns 0 on success. */
     256  GClosure *get_fn;
     257                                /* returns a reference to the current value.
     258                                 * WARNING:  this approach is hard to make
     259                                 * thread-safe... */
     260  GClosure *get_tostring_fn;
     261                                /* converts val to a string;
     262                                 * caller must free the result */
     263  GClosure *delete_fn;
     264                                /* frees val as needed */
     265  GClosure *get_default_fn;
     266                               /* return the default value, as set at creation time */
     267 
     268} owl_variable;
     269
     270typedef struct _owl_variable_init_params {
     271  char *name;
     272  int   type;  /* OWL_VARIABLE_* */
    237273  void *pval_default;  /* for types other and string */
    238274  int   ival_default;  /* for types int and bool     */
     
    241277  char *description;            /* detailed description */
    242278  void *val;                    /* current value */
    243   int  (*validate_fn)(const struct _owl_variable *v, const void *newval);
     279  GCallback validate_fn;
    244280                                /* returns 1 if newval is valid */
    245   int  (*set_fn)(struct _owl_variable *v, const void *newval);
     281  GCallback set_fn;
    246282                                /* sets the variable to a value
    247283                                 * of the appropriate type.
     
    249285                                 * should make a copy.
    250286                                 * returns 0 on success. */
    251   int  (*set_fromstring_fn)(struct _owl_variable *v, const char *newval);
     287  GCallback set_fromstring_fn;
    252288                                /* sets the variable to a value
    253289                                 * of the appropriate type.
     
    255291                                 * should make a copy.
    256292                                 * returns 0 on success. */
    257   const void *(*get_fn)(const struct _owl_variable *v);
     293  GCallback get_fn;
    258294                                /* returns a reference to the current value.
    259295                                 * WARNING:  this approach is hard to make
    260296                                 * thread-safe... */
    261   CALLER_OWN char *(*get_tostring_fn)(const struct _owl_variable *v, const void *val);
     297  GCallback get_tostring_fn;
    262298                                /* converts val to a string;
    263299                                 * caller must free the result */
    264   void (*delete_fn)(struct _owl_variable *v);
     300  GCallback delete_fn;
    265301                                /* frees val as needed */
    266 } owl_variable;
     302  GCallback get_default_fn;
     303                                /* return the default value as set at creation time */
     304} owl_variable_init_params;
     305
    267306
    268307typedef struct _owl_input {
     
    614653#endif
    615654
     655/* We have to dynamically bind these ourselves */
     656extern gboolean (*gvalue_from_sv) (GValue * value, SV * sv);
     657extern SV * (*sv_from_gvalue) (const GValue * value);
     658extern GClosure * (*perl_closure_new) (SV * callback, SV * data, gboolean swap);
     659
     660
    616661#endif /* INC_BARNOWL_OWL_H */
  • perlconfig.c

    r6401db3 r06e04a9  
    559559  SvREFCNT_dec(v);
    560560}
     561
     562void owl_perl_delete_perl_variable(owl_variable *variable, void *data)
     563{
     564  g_closure_unref(variable->delete_fn);
     565  variable->delete_fn = NULL;
     566  SvREFCNT_dec((SV*)data);
     567  owl_variable_delete(variable);
     568}
  • perlglue.xs

    r374089a r06e04a9  
    402402           }
    403403
     404
     405MODULE = BarnOwl                PACKAGE = BarnOwl::Internal
     406
     407void
     408new_variable_full(name, summary, desc, type, data, default_val, get_fn, get_default_fn, tostring_fn, validate_fn, set_fn, fromstring_fn)
     409    const char *name
     410    const char *summary
     411    const char *desc
     412    int type
     413    SV *data
     414    SV *default_val
     415    SV *get_fn
     416    SV *get_default_fn
     417    SV *tostring_fn
     418    SV *validate_fn
     419    SV *set_fn
     420    SV *fromstring_fn
     421    CODE:
     422{
     423        owl_variable *variable = NULL;
     424        int count = 0;
     425        int res = -1;
     426        GClosure *delete_fn = NULL;
     427        if(!SV_IS_CODEREF(get_fn)) {
     428                croak("Get function must be a coderef!");
     429        }
     430        if(!SV_IS_CODEREF(tostring_fn)) {
     431                croak("To-string function must be a coderef!");
     432        }
     433        if(!SV_IS_CODEREF(validate_fn)) {
     434                croak("Validation function must be a coderef!");
     435        }
     436        if(!SV_IS_CODEREF(set_fn)) {
     437                croak("Set function must be a coderef!");
     438        }
     439        if(!SV_IS_CODEREF(fromstring_fn)) {
     440                croak("From-string function must be a coderef!");
     441        }
     442        if(!SV_IS_CODEREF(get_default_fn)) {
     443                croak("Get-default function must be a coderef!");
     444        }
     445        variable = owl_variable_newvar(name, summary, desc);
     446        variable->type = type;
     447        variable->get_fn = perl_closure_new(get_fn, data, false);
     448        variable->get_tostring_fn = perl_closure_new(tostring_fn, data, false);
     449        variable->validate_fn = perl_closure_new(validate_fn, data, false);
     450        variable->set_fn = perl_closure_new(set_fn, data, false);
     451        variable->set_fromstring_fn = perl_closure_new(set_fn, data, false);
     452        variable->get_default_fn = perl_closure_new(get_default_fn,
     453                                                    data, false);
     454        delete_fn = g_cclosure_new(G_CALLBACK(owl_perl_delete_perl_variable),
     455                                           data, NULL);
     456        g_closure_set_marshal(delete_fn,g_cclosure_marshal_VOID__VOID);
     457        g_closure_ref(delete_fn);
     458        g_closure_sink(delete_fn);
     459        variable->delete_fn = delete_fn;
     460
     461        SvREFCNT_inc(data);
     462
     463        PUSHMARK(SP);
     464        XPUSHs(sv_2mortal(newSViv(PTR2IV(variable))));
     465        XPUSHs(default_val);
     466        XPUSHs(data);
     467        PUTBACK;
     468        count = call_sv(set_fn, G_SCALAR | G_EVAL);
     469        SPAGAIN;
     470       
     471        res = POPi;
     472        owl_dict_insert_element(owl_global_get_vardict(&g),
     473                                variable->name, variable, NULL);
     474        PUTBACK;
     475}
     476
    404477void
    405478new_variable_string(name, ival, summ, desc)
  • variable.c

    r8258ea5 r06e04a9  
    11#include "owl.h"
    22#include <stdio.h>
     3#include "gmarshal_funcs.h"
     4
     5static const GType owl_variable_gtype_map[] = {G_TYPE_POINTER,
     6                                               G_TYPE_INT, G_TYPE_BOOLEAN,
     7                                               G_TYPE_STRING };
    38
    49#define OWLVAR_BOOL(name,default,summary,description) \
    510        { g_strdup(name), OWL_VARIABLE_BOOL, NULL, default, "on,off", g_strdup(summary), g_strdup(description), NULL, \
    6         NULL, NULL, NULL, NULL, NULL, NULL }
     11            NULL, NULL, NULL, NULL, NULL, NULL, NULL }
    712
    813#define OWLVAR_BOOL_FULL(name,default,summary,description,validate,set,get) \
    914        { g_strdup(name), OWL_VARIABLE_BOOL, NULL, default, "on,off", g_strdup(summary), g_strdup(description), NULL, \
    10         validate, set, NULL, get, NULL, NULL }
     15            G_CALLBACK(validate), G_CALLBACK(set), NULL, G_CALLBACK(get), NULL, NULL, NULL }
    1116
    1217#define OWLVAR_INT(name,default,summary,description) \
    1318        { g_strdup(name), OWL_VARIABLE_INT, NULL, default, "<int>", g_strdup(summary), g_strdup(description), NULL, \
    14         NULL, NULL, NULL, NULL, NULL, NULL }
     19            NULL, NULL, NULL, NULL, NULL, NULL, NULL }
    1520
    1621#define OWLVAR_INT_FULL(name,default,summary,description,validset,validate,set,get) \
    1722        { g_strdup(name), OWL_VARIABLE_INT, NULL, default, validset, g_strdup(summary), g_strdup(description), NULL, \
    18         validate, set, NULL, get, NULL, NULL }
     23            G_CALLBACK(validate), G_CALLBACK(set), NULL, G_CALLBACK(get), NULL, NULL, NULL }
    1924
    2025#define OWLVAR_PATH(name,default,summary,description) \
    2126        { 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 }
     27            NULL, NULL, NULL, NULL, NULL, NULL, NULL }
    2328
    2429#define OWLVAR_STRING(name,default,summary,description) \
    2530        { 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 }
     31            NULL, NULL, NULL, NULL, NULL, NULL, NULL }
    2732
    2833#define OWLVAR_STRING_FULL(name,default,validset,summary,description,validate,set,get) \
    2934        { 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 }
     35            G_CALLBACK(validate), G_CALLBACK(set), NULL, G_CALLBACK(get), NULL, NULL, NULL }
    3136
    3237/* enums are really integers, but where validset is a comma-separated
     
    3540#define OWLVAR_ENUM(name,default,summary,description,validset) \
    3641        { 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 }
     42            G_CALLBACK(owl_variable_enum_validate),                     \
     43            NULL, G_CALLBACK(owl_variable_enum_set_fromstring),         \
     44            NULL, G_CALLBACK(owl_variable_enum_get_tostring),           \
     45            NULL, NULL }
    4146
    4247#define OWLVAR_ENUM_FULL(name,default,summary,description,validset,validate, set, get) \
    4348        { 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 }
     49            G_CALLBACK(validate),                                       \
     50            G_CALLBACK(set), G_CALLBACK(owl_variable_enum_set_fromstring), \
     51            G_CALLBACK(get), G_CALLBACK(owl_variable_enum_get_tostring), \
     52            NULL, NULL }
    4853
    4954int owl_variable_add_defaults(owl_vardict *vd)
    5055{
    51   owl_variable variables_to_init[] = {
     56  owl_variable_init_params variables_to_init[] = {
    5257
    5358  OWLVAR_STRING( "personalbell" /* %OwlVarStub */, "off",
     
    439444
    440445  int ret = owl_variable_dict_add_from_list(vd, variables_to_init);
    441   owl_variable *var;
     446  owl_variable_init_params *var;
    442447  for (var = variables_to_init; var->name != NULL; var++)
    443     owl_variable_cleanup(var);
     448    owl_variable_cleanup_initializer(var);
    444449  return ret;
    445450}
     
    452457/* commonly useful */
    453458
    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);
     459int owl_variable_int_validate_gt0(const owl_variable *v, const int newval, void *dummy)
     460{
     461  return !(newval < 1);
     462}
     463
     464int owl_variable_int_validate_positive(const owl_variable *v, const int newval, void *dummy)
     465{
     466  return !(newval < 0);
    466467}
    467468
    468469/* typewinsize */
    469 int owl_variable_typewinsize_set(owl_variable *v, const void *newval)
     470int owl_variable_typewinsize_set(owl_variable *v, const int newval, void *dummy)
    470471{
    471472  int rv;
    472   rv = owl_variable_int_set_default(v, newval);
     473  rv = owl_variable_int_set_default(v, newval, dummy);
    473474  if (0 == rv) owl_mainpanel_layout_contents(&g.mainpanel);
    474475  return(rv);
     
    476477
    477478/* 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;
    482   }
    483   return owl_variable_bool_set_default(v, newval);
     479int owl_variable_debug_set(owl_variable *v, const int newval, void *dummy)
     480{
     481  if (newval == 1 || newval == 0) {
     482    g.debug = newval;
     483  }
     484  return owl_variable_bool_set_default(v, newval, dummy);
    484485}
    485486
    486487/* 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)
    500 {
    501   int ret = owl_variable_bool_set_default(v, newval);
     488int owl_variable_aaway_set(owl_variable *v, const gboolean newval, void *dummy)
     489{
     490  if (newval == 1) {
     491    owl_aim_set_awaymsg(owl_global_get_aaway_msg(&g));
     492  } else if (newval == 0) {
     493    owl_aim_set_awaymsg("");
     494  }
     495  return owl_variable_bool_set_default(v, newval, dummy);
     496}
     497
     498int owl_variable_colorztext_set(owl_variable *v, const void *newval, void *dummy)
     499{
     500  int ret = owl_variable_bool_set_default(v, newval, dummy);
    502501  /* flush the format cache so that we see the update, but only if we're done initializing BarnOwl */
    503502  if (owl_global_get_msglist(&g) != NULL)
     
    510509}
    511510
    512 int owl_variable_pseudologins_set(owl_variable *v, const void *newval)
     511int owl_variable_pseudologins_set(owl_variable *v, const int newval, void *dummy)
    513512{
    514513  static guint timer = 0;
    515   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       }
     514  if (newval == 1) {
     515    owl_function_zephyr_buddy_check(0);
     516    if (timer == 0) {
     517      timer = g_timeout_add_seconds(180, owl_zephyr_buddycheck_timer, NULL);
    526518    }
    527   }
    528   return owl_variable_bool_set_default(v, newval);
     519  } else {
     520    if (timer != 0) {
     521      g_source_remove(timer);
     522      timer = 0;
     523    }
     524  }
     525  return owl_variable_bool_set_default(v, newval, dummy);
    529526}
    530527
    531528/* note that changing the value of this will clobber
    532529 * 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) {
     530int owl_variable_disable_ctrl_d_set(owl_variable *v, const int newval, void *dummy)
     531{
     532  if (!owl_context_is_startup(owl_global_get_context(&g))) {
     533    if (newval == 2) {
    537534      owl_function_command_norv("bindkey editmulti C-d command edit:delete-next-char");
    538     } else if (*(const int*)newval == 1) {
     535    } else if (newval == 1) {
    539536      owl_function_command_norv("bindkey editmulti C-d command edit:done-or-delete");
    540537    } else {
     
    542539    }
    543540  } 
    544   return owl_variable_int_set_default(v, newval); 
    545 }
    546 
    547 int owl_variable_tty_set(owl_variable *v, const void *newval)
     541  return owl_variable_int_set_default(v, newval, dummy); 
     542}
     543
     544int owl_variable_tty_set(owl_variable *v, const char *newval, void *dummy)
    548545{
    549546  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)
     547  return(owl_variable_string_set_default(v, newval, dummy));
     548}
     549
     550int owl_variable_default_exposure_set(owl_variable *v, const char *newval, void *dummy)
    554551{
    555552  return owl_zephyr_set_default_exposure(newval);
    556553}
    557554
    558 const void *owl_variable_default_exposure_get(const owl_variable *v)
     555const char *owl_variable_default_exposure_get(const owl_variable *v, void *dummy)
    559556{
    560557  return owl_zephyr_get_default_exposure();
    561558}
    562559
    563 int owl_variable_exposure_set(owl_variable *v, const void *newval)
     560int owl_variable_exposure_set(owl_variable *v, const char *newval, void *dummy)
    564561{
    565562  int ret = owl_zephyr_set_exposure(newval);
    566563  if (ret != 0)
    567564    return ret;
    568   return owl_variable_string_set_default(v, owl_zephyr_normalize_exposure(newval));
     565  return owl_variable_string_set_default(v, owl_zephyr_normalize_exposure(newval), dummy);
    569566}
    570567
     
    578575}
    579576
    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;
     577CALLER_OWN GClosure *owl_variable_make_closure(owl_variable *v,
     578                                                      GCallback fn,
     579                                                      GClosureMarshal marshal) {
     580  GClosure *closure = g_cclosure_new(fn, NULL, NULL);
     581  g_closure_set_marshal(closure,marshal);
     582  g_closure_ref(closure);
     583  g_closure_sink(closure);
     584  return closure;
     585}
     586
     587#define OWL_VARIABLE_SETUP_FUNC(variable, initializer, func_name, default_func, marshal_func, temp) do { \
     588  if(initializer->func_name) { \
     589    temp = initializer->func_name; \
     590  } else { \
     591    temp = default_func; \
     592  } \
     593  variable->func_name = owl_variable_make_closure(variable, G_CALLBACK(temp), \
     594                                                  marshal_func);        \
     595  } while(0)
     596 
     597
     598int owl_variable_dict_add_from_list(owl_vardict *vd, owl_variable_init_params *variables_to_init)
     599{
     600  owl_variable *newvar = NULL;
     601  owl_variable_init_params *init_params = NULL;
     602  for (init_params = variables_to_init; init_params->name; init_params++) {
     603    newvar = g_new0(owl_variable, 1);
     604    newvar->type = init_params->type;
    586605    /* 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;
     606    newvar->name = g_strdup(init_params->name);
     607    newvar->summary = g_strdup(init_params->summary);
     608    newvar->description = g_strdup(init_params->description);
     609    newvar->validsettings = init_params->validsettings;
     610    GValue values[] = {{0}, {0}};
     611    GValue *value = values+1;
     612    GValue ret = {0};
     613    GCallback fn = NULL;
     614    switch (init_params->type) {
    594615    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);
     616      OWL_VARIABLE_SETUP_FUNC(newvar, init_params, get_fn,
     617                              G_CALLBACK(owl_variable_string_get_default),
     618                              g_cclosure_user_marshal_STRING__VOID, fn);
     619      OWL_VARIABLE_SETUP_FUNC(newvar, init_params, set_fn,
     620                              G_CALLBACK(owl_variable_string_set_default),
     621                              g_cclosure_user_marshal_INT__STRING, fn);
     622      OWL_VARIABLE_SETUP_FUNC(newvar, init_params, validate_fn,
     623                              G_CALLBACK(owl_variable_string_validate_default),
     624                              g_cclosure_user_marshal_INT__STRING, fn);
     625      OWL_VARIABLE_SETUP_FUNC(newvar, init_params, set_fromstring_fn,
     626                              G_CALLBACK(owl_variable_string_set_fromstring_default),
     627                              g_cclosure_user_marshal_INT__STRING, fn);
     628      OWL_VARIABLE_SETUP_FUNC(newvar, init_params, get_tostring_fn,
     629                              G_CALLBACK(owl_variable_string_get_tostring_default),
     630                              g_cclosure_user_marshal_STRING__STRING, fn);
     631      OWL_VARIABLE_SETUP_FUNC(newvar, init_params, get_default_fn,
     632                              G_CALLBACK(owl_variable_string_get_default_default),
     633                              g_cclosure_user_marshal_STRING__VOID, fn);
     634
     635      g_value_init(value,G_TYPE_STRING);
     636      g_value_set_string(value, init_params->pval_default);
    609637      break;
    610638    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);
     639      OWL_VARIABLE_SETUP_FUNC(newvar, init_params, get_fn,
     640                              G_CALLBACK(owl_variable_bool_get_default),
     641                              g_cclosure_user_marshal_BOOLEAN__VOID, fn);
     642      OWL_VARIABLE_SETUP_FUNC(newvar, init_params, set_fn,
     643                              G_CALLBACK(owl_variable_bool_set_default),
     644                              g_cclosure_user_marshal_INT__BOOLEAN, fn);
     645      OWL_VARIABLE_SETUP_FUNC(newvar, init_params, validate_fn,
     646                              G_CALLBACK(owl_variable_bool_validate_default),
     647                              g_cclosure_user_marshal_INT__BOOLEAN, fn);
     648      OWL_VARIABLE_SETUP_FUNC(newvar, init_params, set_fromstring_fn,
     649                              G_CALLBACK(owl_variable_bool_set_fromstring_default),
     650                              g_cclosure_user_marshal_INT__STRING, fn);
     651      OWL_VARIABLE_SETUP_FUNC(newvar, init_params, get_tostring_fn,
     652                              G_CALLBACK(owl_variable_bool_get_tostring_default),
     653                              g_cclosure_user_marshal_STRING__BOOLEAN, fn);
     654      OWL_VARIABLE_SETUP_FUNC(newvar, init_params, get_default_fn,
     655                              G_CALLBACK(owl_variable_bool_get_default_default),
     656                              g_cclosure_user_marshal_BOOLEAN__VOID, fn);
     657
     658      g_value_init(value,G_TYPE_BOOLEAN);
     659      g_value_set_boolean(value, !!(init_params->ival_default));
    625660      break;
    626661    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);
     662      OWL_VARIABLE_SETUP_FUNC(newvar, init_params, get_fn,
     663                              G_CALLBACK(owl_variable_int_get_default),
     664                              g_cclosure_user_marshal_INT__VOID, fn);
     665      OWL_VARIABLE_SETUP_FUNC(newvar, init_params, set_fn,
     666                              G_CALLBACK(owl_variable_int_set_default),
     667                              g_cclosure_user_marshal_INT__INT, fn);
     668      OWL_VARIABLE_SETUP_FUNC(newvar, init_params, validate_fn,
     669                              G_CALLBACK(owl_variable_int_validate_default),
     670                              g_cclosure_user_marshal_INT__INT, fn);
     671      OWL_VARIABLE_SETUP_FUNC(newvar, init_params, set_fromstring_fn,
     672                              G_CALLBACK(owl_variable_int_set_fromstring_default),
     673                              g_cclosure_user_marshal_INT__STRING, fn);
     674      OWL_VARIABLE_SETUP_FUNC(newvar, init_params, get_tostring_fn,
     675                              G_CALLBACK(owl_variable_int_get_tostring_default),
     676                              g_cclosure_user_marshal_STRING__INT, fn);
     677      OWL_VARIABLE_SETUP_FUNC(newvar, init_params, get_default_fn,
     678                              G_CALLBACK(owl_variable_int_get_default_default),
     679                              g_cclosure_user_marshal_INT__VOID, fn);
     680
     681      g_value_init(value,G_TYPE_INT);
     682      g_value_set_int(value, init_params->ival_default);
    641683      break;
    642684    default:
     
    644686      return(-2);
    645687    }
    646     owl_dict_insert_element(vd, cur->name, cur, NULL);
     688    OWL_VARIABLE_SETUP_FUNC(newvar, init_params, delete_fn,
     689                            G_CALLBACK(owl_variable_delete_default),
     690                            g_cclosure_marshal_VOID__VOID, fn);
     691   
     692    g_value_init(&(newvar->gval_default), G_VALUE_TYPE(value));
     693    g_value_init(&(newvar->val), G_VALUE_TYPE(value));
     694    g_value_copy(value, &(newvar->gval_default));
     695    /* we have the value boxed up already *anyway*, so... */
     696    g_value_init(values, G_TYPE_POINTER);
     697    g_value_set_pointer(values, newvar);
     698    g_value_init(&ret, G_TYPE_INT);
     699    g_closure_invoke(newvar->set_fn, &ret, 2, values, NULL);
     700    g_value_unset(value);
     701    owl_dict_insert_element(vd, newvar->name, newvar, NULL);
    647702  }
    648703  return 0;
     
    656711CALLER_OWN owl_variable *owl_variable_newvar(const char *name, const char *summary, const char *description)
    657712{
    658   owl_variable * var = g_new0(owl_variable, 1);
     713  owl_variable *var = g_new0(owl_variable, 1);
    659714  var->name = g_strdup(name);
    660715  var->summary = g_strdup(summary);
     
    670725}
    671726
     727#define OWL_VARIABLE_SETUP_DEFAULT_FUNCS(variable, type, gtype) do { \
     728  variable->set_fn = owl_variable_make_closure(variable, \
     729    G_CALLBACK(owl_variable_##type##_set_default), \
     730    g_cclosure_user_marshal_INT__##gtype); \
     731  variable->get_fn = owl_variable_make_closure(variable, \
     732    G_CALLBACK(owl_variable_##type##_get_default), \
     733    g_cclosure_user_marshal_##gtype##__##VOID); \
     734  variable->validate_fn = owl_variable_make_closure(variable, \
     735    G_CALLBACK(owl_variable_##type##_validate_default), \
     736    g_cclosure_user_marshal_INT__##gtype); \
     737  variable->set_fromstring_fn = owl_variable_make_closure(variable, \
     738    G_CALLBACK(owl_variable_##type##_set_fromstring_default), \
     739    g_cclosure_user_marshal_INT__STRING); \
     740  variable->get_tostring_fn = owl_variable_make_closure(variable, \
     741    G_CALLBACK(owl_variable_##type##_get_tostring_default), \
     742    g_cclosure_user_marshal_STRING__##gtype); \
     743  variable->get_default_fn = owl_variable_make_closure(variable, \
     744    G_CALLBACK(owl_variable_##type##_get_default_default), \
     745    g_cclosure_user_marshal_##gtype##__##VOID); \
     746  } while(0);
     747
    672748void owl_variable_dict_newvar_string(owl_vardict *vd, const char *name, const char *summ, const char *desc, const char *initval)
    673749{
     750  GValue default_gvals[] = {{0}, {0}};
     751  GValue *default_gval = default_gvals+1;
     752  GValue retval = {0};
     753  g_value_init(default_gval, G_TYPE_STRING);
     754  g_value_init(&retval, G_TYPE_INT);
     755  g_value_set_static_string(default_gval, initval);
    674756  owl_variable *old = owl_variable_get_var(vd, name);
    675757  if (old && owl_variable_get_type(old) == OWL_VARIABLE_STRING) {
    676758    owl_variable_update(old, summ, desc);
    677     g_free(old->pval_default);
    678     old->pval_default = g_strdup(initval);
     759    g_value_copy(default_gval, &(old->gval_default));
    679760  } else {
    680761    owl_variable * var = owl_variable_newvar(name, summ, desc);
    681762    var->type = OWL_VARIABLE_STRING;
    682763    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);
     764    g_value_init(&(var->val), G_TYPE_STRING);
     765    g_value_init(default_gvals, G_TYPE_POINTER);
     766    g_value_set_pointer(default_gvals, var);
     767    g_value_init(&(var->gval_default), G_TYPE_STRING);
     768    g_value_set_string(&(var->gval_default), initval);
     769    OWL_VARIABLE_SETUP_DEFAULT_FUNCS(var, string, STRING);
     770
     771    g_closure_invoke(var->set_fn, &retval, 2, default_gvals, NULL);
    690772    owl_variable_dict_add_variable(vd, var);
    691773  }
     
    694776void owl_variable_dict_newvar_int(owl_vardict *vd, const char *name, const char *summ, const char *desc, int initval)
    695777{
     778  GValue default_gvals[] = {{0}, {0}};
     779  GValue *default_gval = default_gvals+1;
     780  GValue retval = {0};
     781  g_value_init(default_gval, G_TYPE_INT);
     782  g_value_init(&retval, G_TYPE_INT);
     783  g_value_set_int(default_gval, initval);
    696784  owl_variable *old = owl_variable_get_var(vd, name);
    697785  if (old && owl_variable_get_type(old) == OWL_VARIABLE_INT) {
    698786    owl_variable_update(old, summ, desc);
    699     old->ival_default = initval;
     787    g_value_copy(default_gval, &(old->gval_default));
    700788  } else {
    701789    owl_variable * var = owl_variable_newvar(name, summ, desc);
    702790    var->type = OWL_VARIABLE_INT;
    703791    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);
     792    g_value_init(&(var->val), G_TYPE_INT);
     793    g_value_init(&(var->gval_default), G_TYPE_INT);
     794    OWL_VARIABLE_SETUP_DEFAULT_FUNCS(var, int, INT);
     795    g_value_init(default_gvals, G_TYPE_POINTER);
     796    g_value_set_pointer(default_gvals, var);
     797    g_value_set_int(&(var->gval_default), initval);
     798    g_closure_invoke(var->set_fn, &retval, 2, default_gvals, NULL);
     799    /*    g_value_unset(&retval); */
    713800    owl_variable_dict_add_variable(vd, var);
    714801  }
    715802}
    716803
    717 void owl_variable_dict_newvar_bool(owl_vardict *vd, const char *name, const char *summ, const char *desc, int initval)
    718 {
     804void owl_variable_dict_newvar_bool(owl_vardict *vd, const char *name, const char *summ, const char *desc, gboolean initval)
     805{
     806  GValue default_gvals[] = {{0}, {0}};
     807  GValue *default_gval = default_gvals+1;
     808  GValue retval = {0};
     809  g_value_init(default_gval, G_TYPE_BOOLEAN);
     810  g_value_init(&retval, G_TYPE_INT);
     811  g_value_set_boolean(default_gval, initval);
    719812  owl_variable *old = owl_variable_get_var(vd, name);
    720813  if (old && owl_variable_get_type(old) == OWL_VARIABLE_BOOL) {
    721814    owl_variable_update(old, summ, desc);
    722     old->ival_default = initval;
     815    g_value_copy(default_gval, &(old->gval_default));
    723816  } else {
    724817    owl_variable * var = owl_variable_newvar(name, summ, desc);
    725818    var->type = OWL_VARIABLE_BOOL;
    726819    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);
     820    g_value_init(&(var->val), G_TYPE_BOOLEAN);
     821    g_value_init(&(var->gval_default), G_TYPE_BOOLEAN);
     822    OWL_VARIABLE_SETUP_DEFAULT_FUNCS(var, bool, BOOLEAN);
     823
     824    g_value_init(default_gvals, G_TYPE_POINTER);
     825    g_value_set_pointer(default_gvals, var);
     826    g_value_set_int(&(var->gval_default), initval);
     827    g_closure_invoke(var->set_fn, &retval, 2, default_gvals, NULL); 
    736828    owl_variable_dict_add_variable(vd, var);
    737829  }
     
    749841void owl_variable_cleanup(owl_variable *v)
    750842{
    751   if (v->delete_fn) v->delete_fn(v);
     843  GValue val = {0};
     844  if (v->delete_fn) {
     845    g_value_init(&val, G_TYPE_POINTER);
     846    g_value_set_pointer(&val, v);
     847    g_closure_invoke(v->delete_fn, NULL, 1, &val, NULL);
     848  }
     849  g_free(v->name);
     850  g_free(v->summary);
     851  g_free(v->description);
     852  if (v->type == OWL_VARIABLE_STRING) {
     853    g_value_unset(&v->gval_default);
     854  }
     855  g_closure_unref(v->get_fn);
     856  g_closure_unref(v->set_fn);
     857  g_closure_unref(v->validate_fn);
     858  g_closure_unref(v->get_tostring_fn);
     859  g_closure_unref(v->set_fromstring_fn);
     860}
     861 
     862void owl_variable_cleanup_initializer(owl_variable_init_params *v) {
    752863  g_free(v->name);
    753864  g_free(v->summary);
     
    755866  if (v->type == OWL_VARIABLE_STRING)
    756867    g_free(v->pval_default);
    757 }
     868 }
    758869
    759870void owl_variable_delete(owl_variable *v)
     
    787898
    788899/* functions for getting and setting variable values */
     900
     901static CALLER_OWN  char *owl_variable_invoke_tostring(const owl_variable *v,
     902                                                     const GValue *value)
     903{
     904  GValue values[] = { {0}, {0}};
     905  GValue *value_box = values+1;
     906  GValue tostring_box = {0};
     907  char *ret = NULL;
     908  gboolean need_to_free = false;
     909
     910  g_value_init(values, G_TYPE_POINTER);
     911  g_value_set_pointer(values, (gpointer)v);
     912  g_value_init(&tostring_box, G_TYPE_STRING);
     913  if(value) {
     914    g_value_init(value_box, G_VALUE_TYPE(value));
     915    g_value_copy(value, value_box);
     916    need_to_free = true;
     917  } else {
     918    g_value_init(value_box, owl_variable_gtype_map[v->type]);
     919    g_closure_invoke(v->get_fn, value_box, 1, values, NULL);
     920  }
     921  g_closure_invoke(v->get_tostring_fn,&tostring_box, 2, values, NULL);
     922
     923  ret = g_value_dup_string(&tostring_box);
     924  g_value_unset(&tostring_box);
     925  if(need_to_free) {
     926    g_value_unset(value_box);
     927  }
     928
     929  return ret;
     930}
    789931
    790932/* returns 0 on success, prints a status msg if msg is true */
    791933int owl_variable_set_fromstring(owl_variable *v, const char *value, int msg) {
    792934  char *tostring;
     935  GValue values[] = {{0},{0},{0}};
     936  GValue *value_box = values+1;
     937  GValue return_box = {0};
     938  int set_successfully = -1;
    793939  if (!v->set_fromstring_fn) {
    794940    if (msg) owl_function_error("Variable %s is read-only", owl_variable_get_name(v));
    795941    return -1;   
    796942  }
    797   if (0 != v->set_fromstring_fn(v, value)) {
     943  g_value_init(value_box, G_TYPE_STRING);
     944  g_value_init(values, G_TYPE_POINTER);
     945  g_value_set_pointer(values, v);
     946  g_value_init(&return_box, G_TYPE_INT);
     947  g_value_set_static_string(value_box, value);
     948  g_closure_invoke(v->set_fromstring_fn, &return_box, 2, values, NULL);
     949  set_successfully = g_value_get_int(&return_box);
     950  if (0 != set_successfully) {
    798951    if (msg) owl_function_error("Unable to set %s (must be %s)", owl_variable_get_name(v),
    799952                                owl_variable_get_validsettings(v));
    800     return -1;
    801   }
    802   if (msg) {
    803     tostring = v->get_tostring_fn(v, v->get_fn(v));
    804     if (tostring)
     953  }
     954  if (msg && (0 != set_successfully)) {
     955    tostring = owl_variable_invoke_tostring(v, NULL);
     956    if (tostring) {
    805957      owl_function_makemsg("%s = '%s'", owl_variable_get_name(v), tostring);
    806     else
     958    } else {
    807959      owl_function_makemsg("%s = <null>", owl_variable_get_name(v));
     960    }
    808961    g_free(tostring);
    809   }   
    810   return 0;
     962  }
     963  g_value_unset(value_box);
     964  return set_successfully;
     965}
     966
     967static int owl_variable_invoke_setter(owl_variable *v, const GValue *value) {
     968  GValue values[] = {{0},{0}};
     969  GValue return_box = {0};
     970  int ret = -1;
     971  g_value_init(&return_box, G_TYPE_INT);
     972  g_value_init(values, G_TYPE_POINTER);
     973  g_value_set_pointer(values, v);
     974  g_value_init(values+1, G_VALUE_TYPE(value));
     975  g_value_copy(value, values+1);
     976  g_closure_invoke(v->set_fn, &return_box, 2, values, NULL);
     977  ret = g_value_get_int(&return_box);
     978  /*  g_value_unset(&return_box); */
     979  g_value_unset(values+1);
     980  return ret;
    811981}
    812982 
    813983int owl_variable_set_string(owl_variable *v, const char *newval)
    814984{
     985  int ret = -1;
     986  GValue value_box = {0};
    815987  if (v->type != OWL_VARIABLE_STRING) return -1;
    816   return v->set_fn(v, newval);
    817 }
    818  
     988  g_value_init(&value_box, G_TYPE_STRING);
     989  g_value_set_static_string(&value_box, newval);
     990  ret = owl_variable_invoke_setter(v, &value_box);
     991  g_value_unset(&value_box);
     992  return ret;
     993}
     994
    819995int owl_variable_set_int(owl_variable *v, int newval)
    820996{
     997  int ret = -1;
     998  GValue value_box = {0};
    821999  if (v->type != OWL_VARIABLE_INT && v->type != OWL_VARIABLE_BOOL) return -1;
    822   return v->set_fn(v, &newval);
    823 }
    824  
     1000  g_value_init(&value_box, G_TYPE_INT);
     1001  g_value_set_int(&value_box, newval);
     1002  ret = owl_variable_invoke_setter(v, &value_box);
     1003  /* g_value_unset(&value_box); */
     1004  return ret;
     1005}
     1006
     1007int owl_variable_set_bool(owl_variable *v, gboolean newval) {
     1008  int ret = -1;
     1009  GValue value_box = {0};
     1010  if (v->type != OWL_VARIABLE_BOOL) return -1;
     1011  g_value_init(&value_box, G_TYPE_BOOLEAN);
     1012  g_value_set_int(&value_box, newval);
     1013  ret = owl_variable_invoke_setter(v, &value_box);
     1014  /* g_value_unset(&value_box); */
     1015  return ret;
     1016}
     1017
    8251018int owl_variable_set_bool_on(owl_variable *v)
    8261019{
    8271020  if (v->type != OWL_VARIABLE_BOOL) return -1;
    828   return owl_variable_set_int(v, true);
     1021  return owl_variable_set_bool(v, true);
    8291022}
    8301023
     
    8321025{
    8331026  if (v->type != OWL_VARIABLE_BOOL) return -1;
    834   return owl_variable_set_int(v, false);
     1027  return owl_variable_set_bool(v, false);
    8351028}
    8361029
    8371030CALLER_OWN char *owl_variable_get_tostring(const owl_variable *v)
    8381031{
    839   return v->get_tostring_fn(v, v->get_fn(v));
     1032  return owl_variable_invoke_tostring(v, NULL);
    8401033}
    8411034
    8421035CALLER_OWN char *owl_variable_get_default_tostring(const owl_variable *v)
    8431036{
    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   }
     1037  char *ret = NULL;
     1038  GValue default_value_box = {0};
     1039  GValue variable_box = {0};
     1040  g_value_init(&variable_box, G_TYPE_POINTER);
     1041  g_value_init(&default_value_box, owl_variable_gtype_map[v->type]);
     1042  g_value_set_pointer(&variable_box, (gpointer)v);
     1043  g_closure_invoke(v->get_default_fn, &default_value_box, 1,
     1044                   &variable_box, NULL); 
     1045  ret = owl_variable_invoke_tostring(v, &default_value_box);
     1046  g_value_unset(&default_value_box);
     1047  return ret;
    8491048}
    8501049
     
    8541053}
    8551054
    856 /* returns a reference */
    857 const void *owl_variable_get(const owl_variable *v)
    858 {
    859   return v->get_fn(v);
     1055const GValue *owl_variable_get(const owl_variable *v, GValue *val)
     1056{
     1057  GValue variable_box = {0};
     1058  g_value_init(&variable_box, G_TYPE_POINTER);
     1059  g_value_set_pointer(&variable_box,(gpointer)v);
     1060  g_closure_invoke(v->get_fn, val, 1, &variable_box, NULL); 
     1061  return val;
    8601062}
    8611063
    8621064const char *owl_variable_get_string(const owl_variable *v)
    8631065{
     1066  GValue value = {0};
    8641067  if (owl_variable_get_type(v) != OWL_VARIABLE_STRING) {
    8651068    owl_function_error("Variable '%s' is not a string.", owl_variable_get_name(v));
    8661069    return NULL;
    8671070  }
    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);
     1071  g_value_init(&value, G_TYPE_STRING);
     1072  /* not a leak, since we don't own the underlying string */
     1073  return g_value_get_string(owl_variable_get(v,&value));
    8791074}
    8801075
    8811076int owl_variable_get_int(const owl_variable *v)
    8821077{
     1078  GValue value = {0};
    8831079  if (owl_variable_get_type(v) != OWL_VARIABLE_INT) {
    8841080    owl_function_error("Variable '%s' is an int.", owl_variable_get_name(v));
    8851081    return -1;
    8861082  }
    887   const int *pi = owl_variable_get(v);
    888   if (!pi) return -1;
    889   return *pi;
     1083  g_value_init(&value, G_TYPE_INT);
     1084  return g_value_get_int(owl_variable_get(v,&value));
    8901085}
    8911086
    8921087int owl_variable_get_bool(const owl_variable *v)
    8931088{
     1089  GValue value = {0};
    8941090  if (owl_variable_get_type(v) != OWL_VARIABLE_BOOL) {
    8951091    owl_function_error("Variable '%s' is a boolean.", owl_variable_get_name(v));
    8961092    return -1;
    8971093  }
    898   const int *pi = owl_variable_get(v);
    899   if (!pi) return -1;
    900   return *pi;
     1094  g_value_init(&value, G_TYPE_BOOLEAN);
     1095  return g_value_get_boolean(owl_variable_get(v,&value));
    9011096}
    9021097
     
    9331128  owl_fmtext_append_normal(fm, "\n\n");
    9341129
    935 
    9361130  tostring = owl_variable_get_default_tostring(v);
    9371131  owl_fmtext_append_normal(fm, "Default:        ");
    9381132  owl_fmtext_append_normal(fm, (tostring ? tostring : "<null>"));
    9391133  owl_fmtext_append_normal(fm, "\n\n");
     1134  g_free(tostring);
    9401135
    9411136  owl_fmtext_append_normal(fm, "Valid Settings: ");
     
    9481143    owl_fmtext_append_normal(fm, "\n\n");
    9491144  }
    950   g_free(tostring);
    9511145}
    9521146
     
    9601154/* default common functions */
    9611155
    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);
     1156const char *owl_variable_string_get_default(const owl_variable *v, void *dummy) {
     1157  return g_value_get_string(&(v->val));
     1158}
     1159
     1160const char *owl_variable_string_get_default_default(const owl_variable *v, void *dummy) {
     1161  return g_value_get_string(&(v->gval_default));
     1162}
     1163
     1164
     1165const int owl_variable_int_get_default(const owl_variable *v, void *dummy) {
     1166  return g_value_get_int(&(v->val));
     1167}
     1168
     1169const int owl_variable_int_get_default_default(const owl_variable *v, void *dummy) {
     1170  return g_value_get_int(&(v->gval_default));
     1171}
     1172
     1173
     1174const gboolean owl_variable_bool_get_default(const owl_variable *v, void *dummy) {
     1175  return g_value_get_boolean(&(v->val));
     1176}
     1177
     1178const gboolean owl_variable_bool_get_default_default(const owl_variable *v, void *dummy) {
     1179  return g_value_get_boolean(&(v->gval_default));
     1180}
     1181
     1182
     1183void owl_variable_delete_default(owl_variable *v, void *dummy)
     1184{
     1185  g_value_unset(&(v->val));
    9691186}
    9701187
    9711188/* default functions for booleans */
    9721189
    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) {
     1190int owl_variable_bool_validate_default(const owl_variable *v, const gboolean newval, void *dummy) {
     1191  return (newval == 1) || (newval == 0);
     1192}
     1193
     1194static int owl_variable_invoke_validator(owl_variable *v, const GValue *newval)
     1195{
     1196  GValue values[] = {{0},{0}};
     1197  GValue ret = {0};
     1198  g_value_init(&ret, G_TYPE_INT);
     1199  g_value_init(values, G_TYPE_POINTER);
     1200  g_value_set_pointer(values, v);
     1201  g_value_init(values+1, G_VALUE_TYPE(newval));
     1202  g_value_copy(newval, values+1);
     1203  g_closure_invoke(v->validate_fn, &ret, 2, values, NULL);
     1204  g_value_unset(values+1);
     1205  return g_value_get_int(&ret);
     1206}
     1207
     1208int owl_variable_bool_set_default(owl_variable *v, const bool newval, void *dummy) {
     1209  GValue value = {0};
     1210  g_value_init(&value, G_TYPE_BOOLEAN);
     1211  g_value_set_boolean(&value, newval);
    9801212  if (v->validate_fn) {
    981     if (!v->validate_fn(v, newval)) return(-1);
    982   }
    983   *(int*)v->val = *(const int*)newval;
     1213    if (!owl_variable_invoke_validator(v,&value)) {
     1214      return(-1);
     1215    }
     1216  }
     1217  g_value_set_boolean(&(v->val), newval);
    9841218  return(0);
    9851219}
    9861220
    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) {
     1221int owl_variable_bool_set_fromstring_default(owl_variable *v, const char *newval, void *dummy) {
     1222  gboolean i;
     1223  GValue value = {0};
     1224  if (!strcmp(newval, "on")) {
     1225    i=1;
     1226  } else if (!strcmp(newval, "off")) {
     1227    i=0;
     1228  } else {
     1229    return(-1);
     1230  }
     1231  g_value_init(&value, G_TYPE_BOOLEAN);
     1232  g_value_set_boolean(&value, i);
     1233  return owl_variable_invoke_setter(v,&value);
     1234}
     1235
     1236CALLER_OWN char *owl_variable_bool_get_tostring_default(const owl_variable *v, const bool val, void *dummy)
     1237{
     1238  if (val == 0) {
    10001239    return g_strdup("off");
    1001   } else if (*(const int*)val == 1) {
     1240  } else if (val == 1) {
    10021241    return g_strdup("on");
    10031242  } else {
     
    10081247/* default functions for integers */
    10091248
    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) {
     1249int owl_variable_int_validate_default(const owl_variable *v, const int newval, void *dummy)
     1250{
     1251  return (1);
     1252}
     1253
     1254int owl_variable_int_set_default(owl_variable *v, const int newval, void *dummy) {
     1255  GValue value = {0};
     1256  g_value_init(&value, G_TYPE_INT);
     1257  g_value_set_int(&value, newval);
    10161258  if (v->validate_fn) {
    1017     if (!v->validate_fn(v, newval)) return(-1);
    1018   }
    1019   *(int*)v->val = *(const int*)newval;
     1259    if (!owl_variable_invoke_validator(v,&value)) {
     1260      return(-1);
     1261    }
     1262  }
     1263  g_value_set_int(&(v->val), newval);
    10201264  return(0);
    10211265}
    10221266
    1023 int owl_variable_int_set_fromstring_default(owl_variable *v, const char *newval) {
     1267int owl_variable_int_set_fromstring_default(owl_variable *v, const char *newval, void *dummy) {
    10241268  int i;
    10251269  char *ep;
     1270  GValue value = {0};
    10261271  i = strtol(newval, &ep, 10);
    10271272  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   }
     1273  g_value_init(&value, G_TYPE_INT);
     1274  g_value_set_int(&value, i);
     1275  return owl_variable_invoke_setter(v, &value);
     1276}
     1277
     1278CALLER_OWN char *owl_variable_int_get_tostring_default(const owl_variable *v, const int val, void *dummy)
     1279{
     1280  return g_strdup_printf("%d", val);
    10381281}
    10391282
    10401283/* default functions for enums (a variant of integers) */
    10411284
    1042 int owl_variable_enum_validate(const owl_variable *v, const void *newval) { 
     1285int owl_variable_enum_validate(const owl_variable *v, const int newval, void *dummy) { 
    10431286  char **enums;
    10441287  int nenums, val;
    1045   if (newval == NULL) return(0);
    10461288  enums = g_strsplit_set(v->validsettings, ",", 0);
    10471289  nenums = g_strv_length(enums);
    10481290  g_strfreev(enums);
    1049   val = *(const int*)newval;
     1291  val = newval;
    10501292  if (val < 0 || val >= nenums) {
    10511293    return(0);
     
    10541296}
    10551297
    1056 int owl_variable_enum_set_fromstring(owl_variable *v, const char *newval) {
     1298int owl_variable_enum_set_fromstring(owl_variable *v, const char *newval, void *dummy) {
    10571299  char **enums;
    10581300  int i, val=-1;
     1301  GValue box = {0};
    10591302  if (newval == NULL) return(-1);
    10601303  enums = g_strsplit_set(v->validsettings, ",", 0);
     
    10661309  g_strfreev(enums);
    10671310  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)
     1311  g_value_init(&box, G_TYPE_INT);
     1312  g_value_set_int(&box, val);
     1313  return owl_variable_invoke_setter(v, &box);
     1314}
     1315
     1316CALLER_OWN char *owl_variable_enum_get_tostring(const owl_variable *v, const int val, void *dummy)
    10721317{
    10731318  char **enums;
     
    10751320  char *tostring;
    10761321
    1077   if (val == NULL) {
    1078     return NULL;
    1079   }
    10801322  enums = g_strsplit_set(v->validsettings, ",", 0);
    10811323  nenums = g_strv_length(enums);
    1082   i = *(const int*)val;
     1324  i = val;
    10831325  if (i<0 || i>=nenums) {
    10841326    g_strfreev(enums);
     
    10921334/* default functions for stringeans */
    10931335
    1094 int owl_variable_string_validate_default(const struct _owl_variable *v, const void *newval) {
     1336int owl_variable_string_validate_default(const struct _owl_variable *v, const char *newval, void *dummy) {
    10951337  if (newval == NULL) return(0);
    10961338  else return (1);
    10971339}
    10981340
    1099 int owl_variable_string_set_default(owl_variable *v, const void *newval) {
     1341int owl_variable_string_set_default(owl_variable *v, const char *newval, void *dummy) {
     1342  GValue value = {0};
     1343  g_value_init(&value, G_TYPE_STRING);
     1344  g_value_set_static_string(&value, newval);
    11001345  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);
     1346    if (!owl_variable_invoke_validator(v,&value)) {
     1347      return(-1);
     1348    }
     1349  }
     1350
     1351  /* set_string dups the string for us */
     1352  g_value_set_string(&(v->val), newval);
    11051353  return(0);
    11061354}
    11071355
    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 
     1356int owl_variable_string_set_fromstring_default(owl_variable *v, const char *newval, void *dummy)
     1357{
     1358  GValue val = {0};
     1359  int ret = -1;
     1360  g_value_init(&val, G_TYPE_STRING);
     1361  /* we don't need to dup the string because we don't own it and the setter function we invoke will DTRT */
     1362  g_value_set_static_string(&val, newval);
     1363  ret = owl_variable_invoke_setter(v, &val);
     1364  g_value_unset(&val);
     1365  return ret;
     1366}
     1367
     1368CALLER_OWN char *owl_variable_string_get_tostring_default(const owl_variable *v, const char *val, void *dummy)
     1369{
     1370  if(val) {
     1371    return g_strdup(val);
     1372  } else {
     1373    return g_strdup("");
     1374  }
     1375}
     1376
Note: See TracChangeset for help on using the changeset viewer.