Changeset 69f74c2


Ignore:
Timestamp:
Feb 19, 2013, 8:29:34 PM (8 years ago)
Author:
David Benjamin <davidben@mit.edu>
Branches:
master
Children:
3b9ca71
Parents:
e5210c9
git-author:
David Benjamin <davidben@mit.edu> (06/09/12 23:05:48)
git-committer:
David Benjamin <davidben@mit.edu> (02/19/13 20:29:34)
Message:
And now... the moment you've all been waiting for...

Expose OWL_VARIABLE_OTHER variables to perl. Rewrite all perl variable
entry points to use that one. From now on, C only thinks of these
variables as strings.

(This has one regression to be fixed in a later commit: you can't
set/unset with no arguments since we don't know how to set from
boolean.)
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • owl.h

    r5001a3d r69f74c2  
    239239  char *summary;                /* summary of usage */
    240240  char *description;            /* detailed description */
    241   GValue val;                   /* current value */
    242241  GClosure *set_fromstring_fn;
    243242                                /* sets the variable to a value
     
    251250
    252251  /* These are only valid for OWL_VARIABLE_{INT,BOOL,STRING} */
     252  GValue val;                   /* current value, if default get_fn/set_fn */
     253
    253254  GCallback get_fn;
    254255                                /* returns a reference to the current value.
  • perl/lib/BarnOwl.pm

    r374089a r69f74c2  
    426426
    427427sub new_variable_int {
    428     unshift @_, \&BarnOwl::Internal::new_variable_int, 0;
     428    unshift @_, 0, "<int>", sub { "$_[0]" }, # to string
     429                            sub { $_[0] =~ /^-?[0-9]+$/ }, # validate
     430                            sub { 0 + $_[0] }; # from string
    429431    goto \&_new_variable;
    430432}
    431433
    432434sub new_variable_bool {
    433     unshift @_, \&BarnOwl::Internal::new_variable_bool, 0;
     435    unshift @_, 0, "on,off", sub { $_[0] ? "on" : "off" }, # to string
     436                             sub { $_[0] eq "on" || $_[0] eq "off" }, # validate
     437                             sub { $_[0] eq "on" }; # from string
    434438    goto \&_new_variable;
    435439}
    436440
    437441sub new_variable_string {
    438     unshift @_, \&BarnOwl::Internal::new_variable_string, "";
     442    unshift @_, "", "<string>", sub { $_[0] }, # to string
     443                                sub { 1 }, # validate
     444                                sub { $_[0] }; # from string
    439445    goto \&_new_variable;
    440446}
    441447
    442448sub _new_variable {
    443     my $func = shift;
    444449    my $default_default = shift;
     450    my $validsettings = shift;
     451    my $tostring_fn = shift;
     452    my $validate_fn = shift;
     453    my $fromstring_fn = shift;
     454
    445455    my $name = shift;
    446456    my $args = shift || {};
     
    450460        default     => $default_default,
    451461        %{$args});
    452     $func->($name, $args{default}, $args{summary}, $args{description});
     462
     463    # Store the value in a closure.
     464    my $value = $args{default};
     465
     466    my $get_tostring_fn = sub { $tostring_fn->($value) };
     467    my $set_fromstring_fn = sub {
     468      my ($dummy, $newval) = @_;
     469      return -1 unless $validate_fn->($newval);
     470      $value = $fromstring_fn->($newval);
     471      return 0;
     472    };
     473
     474    BarnOwl::Internal::new_variable($name, $args{summary}, $args{description}, $validsettings,
     475                                    $get_tostring_fn, $set_fromstring_fn, undef);
    453476}
    454477
  • perlglue.xs

    r353719a r69f74c2  
    405405MODULE = BarnOwl                PACKAGE = BarnOwl::Internal
    406406
    407 /* TODO: Revise this after churn is done.
    408 void
    409 new_variable_full(name, summary, desc, type, data, default_val, get_fn, get_default_fn, tostring_fn, validate_fn, set_fn, fromstring_fn)
     407void
     408new_variable(name, summary, description, validsettings, get_tostring_fn, set_fromstring_fn, data)
    410409    const char *name
    411410    const char *summary
    412     const char *desc
    413     int type
     411    const char *description
     412    const char *validsettings
     413    SV *get_tostring_fn
     414    SV *set_fromstring_fn
    414415    SV *data
    415     SV *default_val
    416     SV *get_fn
    417     SV *get_default_fn
    418     SV *tostring_fn
    419     SV *validate_fn
    420     SV *set_fn
    421     SV *fromstring_fn
    422416    CODE:
    423417{
    424         owl_variable *variable = NULL;
    425         int count = 0;
    426         int res = -1;
    427         GClosure *delete_fn = NULL;
    428         if(!SV_IS_CODEREF(get_fn)) {
    429                 croak("Get function must be a coderef!");
    430         }
    431         if(!SV_IS_CODEREF(tostring_fn)) {
     418        /* data is somewhat redundant given we can create closures, but oh
     419         * well. Might be convenient sometimes. */
     420        if(!SV_IS_CODEREF(get_tostring_fn)) {
    432421                croak("To-string function must be a coderef!");
    433422        }
    434         if(!SV_IS_CODEREF(validate_fn)) {
    435                 croak("Validation function must be a coderef!");
    436         }
    437         if(!SV_IS_CODEREF(set_fn)) {
    438                 croak("Set function must be a coderef!");
    439         }
    440         if(!SV_IS_CODEREF(fromstring_fn)) {
     423        if(!SV_IS_CODEREF(set_fromstring_fn)) {
    441424                croak("From-string function must be a coderef!");
    442425        }
    443         if(!SV_IS_CODEREF(get_default_fn)) {
    444                 croak("Get-default function must be a coderef!");
    445         }
    446         variable = owl_variable_newvar(name, summary, desc);
    447         variable->type = type;
    448         variable->get_fn = perl_closure_new(get_fn, data, false);
    449         variable->get_tostring_fn = perl_closure_new(tostring_fn, data, false);
    450         variable->validate_fn = perl_closure_new(validate_fn, data, false);
    451         variable->set_fn = perl_closure_new(set_fn, data, false);
    452         variable->set_fromstring_fn = perl_closure_new(set_fn, data, false);
    453         variable->get_default_fn = perl_closure_new(get_default_fn,
    454                                                     data, false);
    455         delete_fn = g_cclosure_new(G_CALLBACK(owl_perl_delete_perl_variable),
    456                                            data, NULL);
    457         g_closure_set_marshal(delete_fn,g_cclosure_marshal_VOID__VOID);
    458         g_closure_ref(delete_fn);
    459         g_closure_sink(delete_fn);
    460         variable->delete_fn = delete_fn;
    461 
    462         SvREFCNT_inc(data);
    463 
    464         PUSHMARK(SP);
    465         XPUSHs(sv_2mortal(newSViv(PTR2IV(variable))));
    466         XPUSHs(default_val);
    467         XPUSHs(data);
    468         PUTBACK;
    469         count = call_sv(set_fn, G_SCALAR | G_EVAL);
    470         SPAGAIN;
    471        
    472         res = POPi;
    473         owl_dict_insert_element(owl_global_get_vardict(&g),
    474                                 variable->name, variable, NULL);
    475         PUTBACK;
     426
     427        owl_variable_dict_newvar_other(owl_global_get_vardict(&g),
     428                                       name, summary, description, validsettings,
     429                                       perl_closure_new(get_tostring_fn, data, false),
     430                                       perl_closure_new(set_fromstring_fn, data, false));
    476431}
    477 */
    478 
    479 void
    480 new_variable_string(name, ival, summ, desc)
    481         const char * name
    482         const char * ival
    483         const char * summ
    484         const char * desc
    485         CODE:
    486         owl_variable_dict_newvar_string(owl_global_get_vardict(&g),
    487                                         name,
    488                                         summ,
    489                                         desc,
    490                                         ival);
    491 
    492 void
    493 new_variable_int(name, ival, summ, desc)
    494         const char * name
    495         int ival
    496         const char * summ
    497         const char * desc
    498         CODE:
    499         owl_variable_dict_newvar_int(owl_global_get_vardict(&g),
    500                                      name,
    501                                      summ,
    502                                      desc,
    503                                      ival);
    504 
    505 void
    506 new_variable_bool(name, ival, summ, desc)
    507         const char * name
    508         int ival
    509         const char * summ
    510         const char * desc
    511         CODE:
    512         owl_variable_dict_newvar_bool(owl_global_get_vardict(&g),
    513                                       name,
    514                                       summ,
    515                                       desc,
    516                                       ival);
    517432
    518433void
  • variable.c

    r897fc1c r69f74c2  
    680680}
    681681
    682 CALLER_OWN owl_variable *owl_variable_newvar(const char *name, const char *summary, const char *description)
     682void owl_variable_dict_newvar_other(owl_vardict *vd, const char *name, const char *summary, const char *description, const char *validsettings, GClosure *get_tostring_fn, GClosure *set_fromstring_fn)
    683683{
    684684  owl_variable *var = g_new0(owl_variable, 1);
     
    686686  var->summary = g_strdup(summary);
    687687  var->description = g_strdup(description);
    688   return var;
    689 }
    690 
    691 void owl_variable_update(owl_variable *var, const char *summary, const char *desc) {
    692   g_free(var->summary);
    693   var->summary = g_strdup(summary);
    694   g_free(var->description);
    695   var->description = g_strdup(desc);
    696 }
    697 
    698 #define OWL_VARIABLE_SETUP_DEFAULT_FUNCS(variable, type, gtype) do { \
    699   variable->set_fn = G_CALLBACK(owl_variable_##type##_set_default); \
    700   variable->get_fn = G_CALLBACK(owl_variable_##type##_get_default); \
    701   variable->validate_fn = G_CALLBACK(owl_variable_##type##_validate_default); \
    702   variable->set_fromstring_fn = owl_variable_make_closure(variable, \
    703     G_CALLBACK(owl_variable_##type##_set_fromstring_default), \
    704     g_cclosure_user_marshal_INT__STRING); \
    705   variable->get_tostring_fn = owl_variable_make_closure(variable, \
    706     G_CALLBACK(owl_variable_##type##_get_tostring_default), \
    707     g_cclosure_user_marshal_STRING__VOID); \
    708   } while(0)
    709 
    710 void owl_variable_dict_newvar_string(owl_vardict *vd, const char *name, const char *summ, const char *desc, const char *initval)
    711 {
    712   owl_variable *old = owl_variable_get_var(vd, name);
    713   if (old && owl_variable_get_type(old) == OWL_VARIABLE_STRING) {
    714     owl_variable_update(old, summ, desc);
    715     /* g_value_copy(default_gval, &(old->gval_default)); */
    716     /* TODO: Resolve this after churn; this function is only called from perl
    717      * anyway. */
    718   } else {
    719     owl_variable * var = owl_variable_newvar(name, summ, desc);
    720     var->type = OWL_VARIABLE_STRING;
    721     var->validsettings = g_strdup("<string>");
    722     g_value_init(&var->val, G_TYPE_STRING);
    723     OWL_VARIABLE_SETUP_DEFAULT_FUNCS(var, string, STRING);
    724 
    725     owl_variable_set_string(var, initval);
    726 
    727     /* record the initial value as a string */
    728     var->default_str = owl_variable_get_tostring(var);
    729 
    730     owl_variable_dict_add_variable(vd, var);
    731   }
    732 }
    733 
    734 void owl_variable_dict_newvar_int(owl_vardict *vd, const char *name, const char *summ, const char *desc, int initval)
    735 {
    736   owl_variable *old = owl_variable_get_var(vd, name);
    737   if (old && owl_variable_get_type(old) == OWL_VARIABLE_INT) {
    738     owl_variable_update(old, summ, desc);
    739     /* g_value_copy(default_gval, &(old->gval_default)); */
    740     /* TODO: Resolve this after churn; this function is only called from perl
    741      * anyway. */
    742   } else {
    743     owl_variable * var = owl_variable_newvar(name, summ, desc);
    744     var->type = OWL_VARIABLE_INT;
    745     var->validsettings = g_strdup("<int>");
    746     g_value_init(&var->val, G_TYPE_INT);
    747     OWL_VARIABLE_SETUP_DEFAULT_FUNCS(var, int, INT);
    748 
    749     owl_variable_set_int(var, initval);
    750 
    751     /* record the initial value as a string */
    752     var->default_str = owl_variable_get_tostring(var);
    753 
    754     owl_variable_dict_add_variable(vd, var);
    755   }
    756 }
    757 
    758 void owl_variable_dict_newvar_bool(owl_vardict *vd, const char *name, const char *summ, const char *desc, gboolean initval)
    759 {
    760   owl_variable *old = owl_variable_get_var(vd, name);
    761   if (old && owl_variable_get_type(old) == OWL_VARIABLE_BOOL) {
    762     owl_variable_update(old, summ, desc);
    763     /* g_value_copy(default_gval, &(old->gval_default)); */
    764     /* TODO: Resolve this after churn; this function is only called from perl
    765      * anyway. */
    766   } else {
    767     owl_variable * var = owl_variable_newvar(name, summ, desc);
    768     var->type = OWL_VARIABLE_BOOL;
    769     var->validsettings = g_strdup("on,off");
    770     g_value_init(&var->val, G_TYPE_BOOLEAN);
    771     OWL_VARIABLE_SETUP_DEFAULT_FUNCS(var, bool, BOOLEAN);
    772 
    773     owl_variable_set_bool(var, initval);
    774 
    775     /* record the initial value as a string */
    776     var->default_str = owl_variable_get_tostring(var);
    777 
    778     owl_variable_dict_add_variable(vd, var);
    779   }
     688  var->validsettings = g_strdup(validsettings);
     689
     690  var->get_tostring_fn = g_closure_ref(get_tostring_fn);
     691  g_closure_sink(get_tostring_fn);
     692
     693  var->set_fromstring_fn = g_closure_ref(set_fromstring_fn);
     694  g_closure_sink(set_fromstring_fn);
     695
     696  var->default_str = owl_variable_get_tostring(var);
     697
     698  /* Note: this'll overwrite any existing variable of that name, even a C one,
     699     but it's consistent with previous behavior and commands. */
     700  owl_variable_dict_add_variable(vd, var);
    780701}
    781702
Note: See TracChangeset for help on using the changeset viewer.