Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • variable.c

    r6a8b519 r8258ea5  
    11#include "owl.h"
    22#include <stdio.h>
    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 
    10 typedef const char *(*get_string_t)(const owl_variable *);
    11 typedef int (*get_int_t)(const owl_variable *);
    12 typedef bool (*get_bool_t)(const owl_variable *);
    13 
    14 typedef int (*set_string_t)(owl_variable *, const char *);
    15 typedef int (*set_int_t)(owl_variable *, int);
    16 typedef int (*set_bool_t)(owl_variable *, bool);
    17 
    18 typedef int (*validate_string_t)(const owl_variable *, const char *);
    19 typedef int (*validate_int_t)(const owl_variable *, int);
    20 typedef int (*validate_bool_t)(const owl_variable *, bool);
    21 
    22 static 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 
    31 static 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 
    41 static 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 
    51 static 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)
     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 }
    7015
    7116#define OWLVAR_INT_FULL(name,default,summary,description,validset,validate,set,get) \
    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)
     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 }
    8431
    8532/* enums are really integers, but where validset is a comma-separated
    8633 * list of strings which can be specified.  The tokens, starting at 0,
    8734 * correspond to the values that may be specified. */
    88 #define OWLVAR_ENUM(name, default, summary, description, validset) \
    89         owl_variable_dict_newvar_enum(vd, name, default, summary, description, validset)
     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 }
    9041
    9142#define OWLVAR_ENUM_FULL(name,default,summary,description,validset,validate, set, get) \
    92         owl_variable_dict_newvar_enum_full(vd, name, default, summary, description, \
    93                                            validset, validate, set, get)
    94 
    95 void owl_variable_add_defaults(owl_vardict *vd)
    96 {
     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
     49int owl_variable_add_defaults(owl_vardict *vd)
     50{
     51  owl_variable variables_to_init[] = {
     52
    9753  OWLVAR_STRING( "personalbell" /* %OwlVarStub */, "off",
    9854                 "ring the terminal bell when personal messages are received",
    9955                 "Can be set to 'on', 'off', or the name of a filter which\n"
    100                  "messages need to match in order to ring the bell");
     56                 "messages need to match in order to ring the bell"),
    10157
    10258  OWLVAR_BOOL( "bell" /* %OwlVarStub */, 1,
    103                "enable / disable the terminal bell", "" );
     59               "enable / disable the terminal bell", "" ),
    10460
    10561  OWLVAR_BOOL_FULL( "debug" /* %OwlVarStub */, OWL_DEBUG,
     
    10763                    "If set to 'on', debugging messages are logged to the\n"
    10864                    "file specified by the debugfile variable.\n",
    109                     NULL, owl_variable_debug_set, NULL);
     65                    NULL, owl_variable_debug_set, NULL),
    11066
    11167  OWLVAR_BOOL( "startuplogin" /* %OwlVarStub */, 1,
    112                "send a login message when BarnOwl starts", "" );
     68               "send a login message when BarnOwl starts", "" ),
    11369
    11470  OWLVAR_BOOL( "shutdownlogout" /* %OwlVarStub */, 1,
    115                "send a logout message when BarnOwl exits", "" );
     71               "send a logout message when BarnOwl exits", "" ),
    11672
    11773  OWLVAR_BOOL( "rxping" /* %OwlVarStub */, 0,
    118                "display received pings", "" );
     74               "display received pings", "" ),
    11975
    12076  OWLVAR_BOOL( "txping" /* %OwlVarStub */, 1,
    121                "send pings", "" );
     77               "send pings", "" ),
    12278
    12379  OWLVAR_BOOL( "sepbar_disable" /* %OwlVarStub */, 0,
    124                "disable printing information in the separator bar", "" );
     80               "disable printing information in the separator bar", "" ),
    12581
    12682  OWLVAR_BOOL( "smartstrip" /* %OwlVarStub */, 1,
    127                "strip kerberos instance for reply", "");
     83               "strip kerberos instance for reply", ""),
    12884
    12985  OWLVAR_BOOL( "newlinestrip" /* %OwlVarStub */, 1,
    130                "strip leading and trailing newlines", "");
     86               "strip leading and trailing newlines", ""),
    13187
    13288  OWLVAR_BOOL( "displayoutgoing" /* %OwlVarStub */, 1,
    133                "display outgoing messages", "" );
     89               "display outgoing messages", "" ),
    13490
    13591  OWLVAR_BOOL( "loginsubs" /* %OwlVarStub */, 1,
    136                "load logins from .anyone on startup", "" );
     92               "load logins from .anyone on startup", "" ),
    13793
    13894  OWLVAR_BOOL( "logging" /* %OwlVarStub */, 0,
     
    14197               "logged in the directory specified\n"
    14298               "by the 'logpath' variable.  The filename in that\n"
    143                "directory is derived from the sender of the message.\n" );
     99               "directory is derived from the sender of the message.\n" ),
    144100
    145101  OWLVAR_BOOL( "classlogging" /* %OwlVarStub */, 0,
     
    149105               "by the 'classlogpath' variable.\n"
    150106               "The filename in that directory is derived from\n"
    151                "the name of the class to which the message was sent.\n" );
     107               "the name of the class to which the message was sent.\n" ),
    152108
    153109  OWLVAR_ENUM( "loggingdirection" /* %OwlVarStub */, OWL_LOGGING_DIRECTION_BOTH,
     
    158114               "is selected both incoming and outgoing messages are\n"
    159115               "logged.",
    160                "both,in,out");
     116               "both,in,out"),
    161117
    162118  OWLVAR_BOOL_FULL( "colorztext" /* %OwlVarStub */, 1,
    163119                    "allow @color() in zephyrs to change color",
    164                     NULL, NULL, owl_variable_colorztext_set, NULL);
     120                    NULL, NULL, owl_variable_colorztext_set, NULL),
    165121
    166122  OWLVAR_BOOL( "fancylines" /* %OwlVarStub */, 1,
     
    168124               "If turned off, dashes, pipes and pluses will be used\n"
    169125               "to draw lines on the screen.  Useful when the terminal\n"
    170                "is causing problems" );
     126               "is causing problems" ),
    171127
    172128  OWLVAR_BOOL( "zcrypt" /* %OwlVarStub */, 1,
    173129               "Do automatic zcrypt processing",
    174                "" );
     130               "" ),
    175131
    176132  OWLVAR_BOOL_FULL( "pseudologins" /* %OwlVarStub */, 0,
     
    180136                    "but sent no login message, or a user is not present that sent no\n"
    181137                    "logout message, a pseudo login or logout message will be created\n",
    182                     NULL, owl_variable_pseudologins_set, NULL);
     138                    NULL, owl_variable_pseudologins_set, NULL),
    183139
    184140  OWLVAR_BOOL( "ignorelogins" /* %OwlVarStub */, 0,
     
    186142               "When this is enabled, BarnOwl will print login and logout notifications\n"
    187143               "for AIM, zephyr, or other protocols.  If disabled BarnOwl will not print\n"
    188                "login or logout notifications.\n");
     144               "login or logout notifications.\n"),
    189145
    190146  OWLVAR_STRING( "logfilter" /* %OwlVarStub */, "",
     
    195151                 "variables like logging, classlogging, loglogins, loggingdirection,\n"
    196152                 "etc.  If you want this variable to control all logging, make sure\n"
    197                  "all other logging variables are in their default state.\n");
     153                 "all other logging variables are in their default state.\n"),
    198154
    199155  OWLVAR_BOOL( "loglogins" /* %OwlVarStub */, 0,
     
    201157               "When this is enabled, BarnOwl will log login and logout notifications\n"
    202158               "for AIM, zephyr, or other protocols.  If disabled BarnOwl will not print\n"
    203                "login or logout notifications.\n");
     159               "login or logout notifications.\n"),
    204160
    205161  OWLVAR_ENUM_FULL( "disable-ctrl-d" /* %OwlVarStub:lockout_ctrld */, 1,
     
    213169                    "in the editmulti keymap.\n",
    214170                    "off,middle,on",
    215                     NULL, owl_variable_disable_ctrl_d_set, NULL);
     171                    NULL, owl_variable_disable_ctrl_d_set, NULL),
    216172
    217173  OWLVAR_PATH( "logpath" /* %OwlVarStub */, "~/zlog/people",
    218174               "path for logging personal zephyrs",
    219175               "Specifies a directory which must exist.\n"
    220                "Files will be created in the directory for each sender.\n");
     176               "Files will be created in the directory for each sender.\n"),
    221177
    222178  OWLVAR_PATH( "classlogpath" /* %OwlVarStub:classlogpath */, "~/zlog/class",
    223179               "path for logging class zephyrs",
    224180               "Specifies a directory which must exist.\n"
    225                "Files will be created in the directory for each class.\n");
     181               "Files will be created in the directory for each class.\n"),
    226182
    227183  OWLVAR_PATH( "debug_file" /* %OwlVarStub */, OWL_DEBUG_FILE,
    228184               "path for logging debug messages when debugging is enabled",
    229185               "This file will be logged to if 'debug' is set to 'on'.\n"
    230                "BarnOwl will append a dot and the current process's pid to the filename.");
     186               "BarnOwl will append a dot and the current process's pid to the filename."),
    231187 
    232188  OWLVAR_PATH( "zsigproc" /* %OwlVarStub:zsigproc */, NULL,
     
    236192               "See the documentation for 'zsig' for more information about\n"
    237193               "how the outgoing zsig is chosen."
    238                );
     194               ),
    239195
    240196  OWLVAR_PATH( "newmsgproc" /* %OwlVarStub:newmsgproc */, NULL,
     
    242198               "The named program will be run when BarnOwl receives new\n"
    243199               "messages.  It will not be run again until the first\n"
    244                "instance exits");
     200               "instance exits"),
    245201
    246202  OWLVAR_STRING( "zsender" /* %OwlVarStub */, "",
     
    249205         "zephyrs.  If this is unset, it will use your Kerberos\n"
    250206         "principal. Note that customizing the sender name will\n"
    251          "cause your zephyrs to be sent unauthenticated.");
     207         "cause your zephyrs to be sent unauthenticated."),
    252208
    253209  OWLVAR_STRING( "zsigfunc" /* %OwlVarStub */, "BarnOwl::default_zephyr_signature()",
     
    256212                 "explicit zsig.  The default setting implements the policy\n"
    257213                 "described in the documentation for the 'zsig' variable.\n"
    258                  "See also BarnOwl::random_zephyr_signature().\n");
     214                 "See also BarnOwl::random_zephyr_signature().\n"),
    259215
    260216  OWLVAR_STRING( "zsig" /* %OwlVarStub */, "",
     
    263219                 "unset, 'zsigproc' will be run to generate a zsig. If that is\n"
    264220                 "also unset, the 'zwrite-signature' zephyr variable will be\n"
    265                  "used instead.\n");
     221                 "used instead.\n"),
    266222
    267223  OWLVAR_STRING( "appendtosepbar" /* %OwlVarStub */, "",
     
    269225                 "The sepbar is the bar separating the top and bottom\n"
    270226                 "of the BarnOwl screen.  Any string specified here will\n"
    271                  "be displayed on the right of the sepbar\n");
     227                 "be displayed on the right of the sepbar\n"),
    272228
    273229  OWLVAR_BOOL( "zaway" /* %OwlVarStub */, 0,
    274                "turn zaway on or off", "" );
     230               "turn zaway on or off", "" ),
    275231
    276232  OWLVAR_STRING( "zaway_msg" /* %OwlVarStub */,
    277233                 OWL_DEFAULT_ZAWAYMSG,
    278                  "zaway msg for responding to zephyrs when away", "" );
     234                 "zaway msg for responding to zephyrs when away", "" ),
    279235
    280236  OWLVAR_STRING( "zaway_msg_default" /* %OwlVarStub */,
    281237                 OWL_DEFAULT_ZAWAYMSG,
    282                  "default zaway message", "" );
     238                 "default zaway message", "" ),
    283239
    284240  OWLVAR_BOOL_FULL( "aaway" /* %OwlVarStub */, 0,
    285241                    "Set AIM away status",
    286242                    "",
    287                     NULL, owl_variable_aaway_set, NULL);
     243                    NULL, owl_variable_aaway_set, NULL),
    288244
    289245  OWLVAR_STRING( "aaway_msg" /* %OwlVarStub */,
    290246                 OWL_DEFAULT_AAWAYMSG,
    291                  "AIM away msg for responding when away", "" );
     247                 "AIM away msg for responding when away", "" ),
    292248
    293249  OWLVAR_STRING( "aaway_msg_default" /* %OwlVarStub */,
    294250                 OWL_DEFAULT_AAWAYMSG,
    295                  "default AIM away message", "" );
     251                 "default AIM away message", "" ),
    296252
    297253  OWLVAR_STRING( "view_home" /* %OwlVarStub */, "all",
    298254                 "home view to switch to after 'X' and 'V'",
    299                  "SEE ALSO: view, filter\n" );
     255                 "SEE ALSO: view, filter\n" ),
    300256
    301257  OWLVAR_STRING( "alert_filter" /* %OwlVarStub */, "none",
    302258                 "filter on which to trigger alert actions",
    303                  "" );
     259                 "" ),
    304260
    305261  OWLVAR_STRING( "alert_action" /* %OwlVarStub */, "nop",
    306262                 "BarnOwl command to execute for alert actions",
    307                  "" );
     263                 "" ),
    308264
    309265  OWLVAR_STRING_FULL( "tty" /* %OwlVarStub */, "", "<string>", "tty name for zephyr location", "",
    310                       NULL, owl_variable_tty_set, NULL);
     266                      NULL, owl_variable_tty_set, NULL),
    311267
    312268  OWLVAR_STRING( "default_style" /* %OwlVarStub */, "default",
     
    319275                 "   perl     - legacy perl interface\n"
    320276                 "\nSEE ALSO: style, show styles, view -s <style>\n"
    321                  );
     277                 ),
    322278
    323279
     
    326282                 "This specifies the maximum number of columns for M-q to fill text\n"
    327283                 "to.  If set to 0, M-q will wrap to the width of the window, and\n"
    328                  "values less than 0 disable M-q entirely.\n");
     284                 "values less than 0 disable M-q entirely.\n"),
    329285
    330286  OWLVAR_INT(    "edit:maxwrapcols" /* %OwlVarStub:edit_maxwrapcols */, 70,
     
    335291                 "\n"
    336292                 "As a courtesy to recipients, it is recommended that outgoing\n"
    337                  "Zephyr messages be no wider than 70 columns.\n");
     293                 "Zephyr messages be no wider than 70 columns.\n"),
    338294
    339295  OWLVAR_INT( "aim_ignorelogin_timer" /* %OwlVarStub */, 15,
     
    342298              "AIM login before allowing the receipt of AIM login notifications.\n"
    343299              "By default this is set to 15.  If you would like to view login\n"
    344               "notifications of buddies as soon as you login, set it to 0 instead.");
     300              "notifications of buddies as soon as you login, set it to 0 instead."),
    345301
    346302             
     
    355311                   owl_variable_typewinsize_set,
    356312                   NULL /* use default for get */
    357                    );
     313                   ),
    358314
    359315  OWLVAR_INT( "typewindelta" /* %OwlVarStub */, 0,
     
    365321           "typewinsize to 1.\n\n"
    366322           "This works a lot better with a non-default scrollmode;\n"
    367            "try :set scrollmode pagedcenter.\n");
     323           "try :set scrollmode pagedcenter.\n"),
    368324
    369325  OWLVAR_ENUM( "scrollmode" /* %OwlVarStub */, OWL_SCROLLMODE_NORMAL,
     
    394350               "                 the screen will be paged up or down and\n"
    395351               "                 the cursor will be near the center.\n",
    396                "normal,top,neartop,center,paged,pagedcenter" );
     352               "normal,top,neartop,center,paged,pagedcenter" ),
    397353
    398354  OWLVAR_BOOL( "narrow-related" /* %OwlVarStub:narrow_related */, 1,
     
    402358               "for Zephyr, this controls whether to narrow to e.g. class-help or\n"
    403359               "class-help.d alone, or to related-class-help, which includes\n"
    404                "help, unhelp, help.d, etc.\n\nDefault is true (include unclasses, etc.).\n" );
     360               "help, unhelp, help.d, etc.\n\nDefault is true (include unclasses, etc.).\n" ),
    405361
    406362  OWLVAR_BOOL( "_followlast" /* %OwlVarStub */, 0,
     
    409365               "continue to follow the last message if this is set.\n"
    410366               "Note that this is currently risky as you might accidentally\n"
    411                "delete a message right as it came in.\n" );
     367               "delete a message right as it came in.\n" ),
    412368
    413369  OWLVAR_STRING_FULL( "default_exposure" /* %OwlVarStub */, "",
     
    418374                      "~/.zephyr.vars.\n"
    419375                      "See the description of exposure for the values this can be.",
    420                       NULL, owl_variable_default_exposure_set, owl_variable_default_exposure_get );
     376                      NULL, owl_variable_default_exposure_set, owl_variable_default_exposure_get ),
    421377
    422378  OWLVAR_STRING_FULL( "exposure" /* %OwlVarStub */, "",
     
    474430                      "                     personal subscriptions will be entered for the\n"
    475431                      "                     user.\n",
    476                       NULL, owl_variable_exposure_set, NULL /* use default for get */ );
     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;
    477445}
    478446
     
    484452/* commonly useful */
    485453
    486 int owl_variable_int_validate_gt0(const owl_variable *v, int newval)
    487 {
    488   return !(newval < 1);
    489 }
    490 
    491 int owl_variable_int_validate_positive(const owl_variable *v, int newval)
    492 {
    493   return !(newval < 0);
     454int 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
     461int 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);
    494466}
    495467
    496468/* typewinsize */
    497 int owl_variable_typewinsize_set(owl_variable *v, int newval)
     469int owl_variable_typewinsize_set(owl_variable *v, const void *newval)
    498470{
    499471  int rv;
     
    504476
    505477/* debug (cache value in g->debug) */
    506 int owl_variable_debug_set(owl_variable *v, bool newval)
    507 {
    508   g.debug = newval;
     478int 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  }
    509483  return owl_variable_bool_set_default(v, newval);
    510484}
    511485
    512486/* When 'aaway' is changed, need to notify the AIM server */
    513 int owl_variable_aaway_set(owl_variable *v, bool newval)
     487int owl_variable_aaway_set(owl_variable *v, const void *newval)
    514488{
    515489  if (newval) {
    516     owl_aim_set_awaymsg(owl_global_get_aaway_msg(&g));
    517   } else {
    518     owl_aim_set_awaymsg("");
     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    }
    519495  }
    520496  return owl_variable_bool_set_default(v, newval);
    521497}
    522498
    523 int owl_variable_colorztext_set(owl_variable *v, bool newval)
     499int owl_variable_colorztext_set(owl_variable *v, const void *newval)
    524500{
    525501  int ret = owl_variable_bool_set_default(v, newval);
     
    534510}
    535511
    536 int owl_variable_pseudologins_set(owl_variable *v, bool newval)
     512int owl_variable_pseudologins_set(owl_variable *v, const void *newval)
    537513{
    538514  static guint timer = 0;
    539515  if (newval) {
    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;
     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      }
    548526    }
    549527  }
     
    553531/* note that changing the value of this will clobber
    554532 * any user setting of this */
    555 int 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) {
     533int 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) {
    559537      owl_function_command_norv("bindkey editmulti C-d command edit:delete-next-char");
    560     } else if (newval == 1) {
     538    } else if (*(const int*)newval == 1) {
    561539      owl_function_command_norv("bindkey editmulti C-d command edit:done-or-delete");
    562540    } else {
     
    564542    }
    565543  } 
    566   return owl_variable_int_set_default(v, newval);
    567 }
    568 
    569 int owl_variable_tty_set(owl_variable *v, const char *newval)
     544  return owl_variable_int_set_default(v, newval); 
     545}
     546
     547int owl_variable_tty_set(owl_variable *v, const void *newval)
    570548{
    571549  owl_zephyr_set_locationinfo(g_get_host_name(), newval);
    572   return owl_variable_string_set_default(v, newval);
    573 }
    574 
    575 int owl_variable_default_exposure_set(owl_variable *v, const char *newval)
     550  return(owl_variable_string_set_default(v, newval));
     551}
     552
     553int owl_variable_default_exposure_set(owl_variable *v, const void *newval)
    576554{
    577555  return owl_zephyr_set_default_exposure(newval);
    578556}
    579557
    580 const char *owl_variable_default_exposure_get(const owl_variable *v)
     558const void *owl_variable_default_exposure_get(const owl_variable *v)
    581559{
    582560  return owl_zephyr_get_default_exposure();
    583561}
    584562
    585 int owl_variable_exposure_set(owl_variable *v, const char *newval)
     563int owl_variable_exposure_set(owl_variable *v, const void *newval)
    586564{
    587565  int ret = owl_zephyr_set_exposure(newval);
     
    595573/**************************************************************************/
    596574
    597 void owl_variable_dict_setup(owl_vardict *vd) {
     575int owl_variable_dict_setup(owl_vardict *vd) {
    598576  owl_dict_create(vd);
    599   owl_variable_add_defaults(vd);
    600 }
    601 
    602 CALLER_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;
     577  return owl_variable_add_defaults(vd);
     578}
     579
     580int 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;
    610649}
    611650
     
    615654}
    616655
    617 static 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;
     656CALLER_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);
    620659  var->name = g_strdup(name);
    621660  var->summary = g_strdup(summary);
    622661  var->description = g_strdup(description);
    623   var->validsettings = g_strdup(validsettings);
    624662  return var;
    625663}
    626664
    627 static 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 
    650 void 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 
    655 static 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 
    678 void 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 
    683 static 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 
    706 void 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 
    711 void 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 
    716 static 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 
    739 void 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 
    744 void 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);
     665void 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
     672void 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
     694void 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
     717void 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  }
    761738}
    762739
     
    770747}
    771748
    772 void owl_variable_delete(owl_variable *v)
    773 {
     749void owl_variable_cleanup(owl_variable *v)
     750{
     751  if (v->delete_fn) v->delete_fn(v);
    774752  g_free(v->name);
    775753  g_free(v->summary);
    776754  g_free(v->description);
    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 
     755  if (v->type == OWL_VARIABLE_STRING)
     756    g_free(v->pval_default);
     757}
     758
     759void owl_variable_delete(owl_variable *v)
     760{
     761  owl_variable_cleanup(v);
    783762  g_free(v);
    784763}
     
    806785  return v->type;
    807786}
     787
     788/* functions for getting and setting variable values */
    808789
    809790/* returns 0 on success, prints a status msg if msg is true */
    810791int owl_variable_set_fromstring(owl_variable *v, const char *value, int msg) {
    811792  char *tostring;
    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) {
     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)) {
    825798    if (msg) owl_function_error("Unable to set %s (must be %s)", owl_variable_get_name(v),
    826799                                owl_variable_get_validsettings(v));
    827   } else if (msg) {
    828     tostring = owl_variable_get_tostring(v);
    829     if (tostring) {
     800    return -1;
     801  }
     802  if (msg) {
     803    tostring = v->get_tostring_fn(v, v->get_fn(v));
     804    if (tostring)
    830805      owl_function_makemsg("%s = '%s'", owl_variable_get_name(v), tostring);
    831     } else {
     806    else
    832807      owl_function_makemsg("%s = <null>", owl_variable_get_name(v));
    833     }
    834808    g_free(tostring);
    835   }
    836 
    837   g_value_unset(&return_box);
    838   g_value_unset(&values[1]);
    839   g_value_unset(&values[0]);
    840   return set_successfully;
     809  }   
     810  return 0;
    841811}
    842812 
    843813int owl_variable_set_string(owl_variable *v, const char *newval)
    844814{
    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 
     815  if (v->type != OWL_VARIABLE_STRING) return -1;
     816  return v->set_fn(v, newval);
     817}
     818 
    851819int owl_variable_set_int(owl_variable *v, int newval)
    852820{
    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 
    859 int 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 
     821  if (v->type != OWL_VARIABLE_INT && v->type != OWL_VARIABLE_BOOL) return -1;
     822  return v->set_fn(v, &newval);
     823}
     824 
    866825int owl_variable_set_bool_on(owl_variable *v)
    867826{
    868827  if (v->type != OWL_VARIABLE_BOOL) return -1;
    869   return owl_variable_set_bool(v, true);
     828  return owl_variable_set_int(v, true);
    870829}
    871830
     
    873832{
    874833  if (v->type != OWL_VARIABLE_BOOL) return -1;
    875   return owl_variable_set_bool(v, false);
     834  return owl_variable_set_int(v, false);
    876835}
    877836
    878837CALLER_OWN char *owl_variable_get_tostring(const owl_variable *v)
    879838{
    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 
    896 const char *owl_variable_get_default_tostring(const owl_variable *v)
    897 {
    898   return v->default_str;
     839  return v->get_tostring_fn(v, v->get_fn(v));
     840}
     841
     842CALLER_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  }
    899849}
    900850
     
    904854}
    905855
     856/* returns a reference */
     857const void *owl_variable_get(const owl_variable *v)
     858{
     859  return v->get_fn(v);
     860}
     861
    906862const char *owl_variable_get_string(const owl_variable *v)
    907863{
    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);
     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 */
     872const 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);
    912879}
    913880
    914881int owl_variable_get_int(const owl_variable *v)
    915882{
    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 
    922 bool 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);
     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
     892int 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;
    928901}
    929902
    930903void owl_variable_describe(const owl_variable *v, owl_fmtext *fm)
    931904{
    932   const char *default_str = owl_variable_get_default_tostring(v);
     905  char *tostring = owl_variable_get_default_tostring(v);
    933906  char *default_buf;
    934907
    935   if (default_str)
    936     default_buf = g_strdup_printf("'%s'", default_str);
     908  if (tostring)
     909    default_buf = g_strdup_printf("'%s'", tostring);
    937910  else
    938911    default_buf = g_strdup("<null>");
     
    941914                            owl_variable_get_summary(v), default_buf);
    942915  g_free(default_buf);
     916  g_free(tostring);
    943917}
    944918
    945919void owl_variable_get_help(const owl_variable *v, owl_fmtext *fm) {
    946920  char *tostring;
    947   const char *default_str;
    948921
    949922  owl_fmtext_append_bold(fm, "OWL VARIABLE\n\n");
     
    960933  owl_fmtext_append_normal(fm, "\n\n");
    961934
    962   default_str = owl_variable_get_default_tostring(v);
     935
     936  tostring = owl_variable_get_default_tostring(v);
    963937  owl_fmtext_append_normal(fm, "Default:        ");
    964   owl_fmtext_append_normal(fm, (default_str ? default_str : "<null>"));
     938  owl_fmtext_append_normal(fm, (tostring ? tostring : "<null>"));
    965939  owl_fmtext_append_normal(fm, "\n\n");
    966940
     
    974948    owl_fmtext_append_normal(fm, "\n\n");
    975949  }
     950  g_free(tostring);
    976951}
    977952
     
    985960/* default common functions */
    986961
    987 const char *owl_variable_string_get_default(const owl_variable *v) {
    988   return g_value_get_string(&(v->val));
    989 }
    990 
    991 int owl_variable_int_get_default(const owl_variable *v) {
    992   return g_value_get_int(&(v->val));
    993 }
    994 
    995 bool owl_variable_bool_get_default(const owl_variable *v) {
    996   return g_value_get_boolean(&(v->val));
     962const void *owl_variable_get_default(const owl_variable *v) {
     963  return v->val;
     964}
     965
     966void owl_variable_delete_default(owl_variable *v)
     967{
     968  g_free(v->val);
    997969}
    998970
    999971/* default functions for booleans */
    1000972
    1001 int owl_variable_bool_validate_default(const owl_variable *v, bool newval) {
    1002   return (newval == 1) || (newval == 0);
    1003 }
    1004 
    1005 int 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);
     973int 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
     979int 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);
     982  }
     983  *(int*)v->val = *(const int*)newval;
    1010984  return(0);
    1011985}
    1012986
    1013 int 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);
    1021   }
    1022 
    1023   return owl_variable_set_bool(v, i);
    1024 }
    1025 
    1026 CALLER_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) {
     987int 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
     995CALLER_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) {
    10301000    return g_strdup("off");
    1031   } else if (val == 1) {
     1001  } else if (*(const int*)val == 1) {
    10321002    return g_strdup("on");
    10331003  } else {
     
    10381008/* default functions for integers */
    10391009
    1040 int owl_variable_int_validate_default(const owl_variable *v, int newval)
    1041 {
    1042   return (1);
    1043 }
    1044 
    1045 int 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);
     1010int owl_variable_int_validate_default(const owl_variable *v, const void *newval) {
     1011  if (newval == NULL) return(0);
     1012  else return (1);
     1013}
     1014
     1015int 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;
    10501020  return(0);
    10511021}
    10521022
    1053 int owl_variable_int_set_fromstring_default(owl_variable *v, const char *newval, void *dummy) {
     1023int owl_variable_int_set_fromstring_default(owl_variable *v, const char *newval) {
    10541024  int i;
    10551025  char *ep;
    10561026  i = strtol(newval, &ep, 10);
    10571027  if (*ep || ep==newval) return(-1);
    1058   return owl_variable_set_int(v, i);
    1059 }
    1060 
    1061 CALLER_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));
     1028  return (v->set_fn(v, &i));
     1029}
     1030
     1031CALLER_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  }
    10641038}
    10651039
    10661040/* default functions for enums (a variant of integers) */
    10671041
    1068 int owl_variable_enum_validate(const owl_variable *v, int newval) {
     1042int owl_variable_enum_validate(const owl_variable *v, const void *newval) { 
    10691043  char **enums;
    10701044  int nenums, val;
     1045  if (newval == NULL) return(0);
    10711046  enums = g_strsplit_set(v->validsettings, ",", 0);
    10721047  nenums = g_strv_length(enums);
    10731048  g_strfreev(enums);
    1074   val = newval;
     1049  val = *(const int*)newval;
    10751050  if (val < 0 || val >= nenums) {
    10761051    return(0);
     
    10791054}
    10801055
    1081 int owl_variable_enum_set_fromstring(owl_variable *v, const char *newval, void *dummy) {
     1056int owl_variable_enum_set_fromstring(owl_variable *v, const char *newval) {
    10821057  char **enums;
    10831058  int i, val=-1;
     
    10911066  g_strfreev(enums);
    10921067  if (val == -1) return(-1);
    1093   return owl_variable_set_int(v, val);
    1094 }
    1095 
    1096 CALLER_OWN char *owl_variable_enum_get_tostring(const owl_variable *v, void *dummy)
     1068  return (v->set_fn(v, &val));
     1069}
     1070
     1071CALLER_OWN char *owl_variable_enum_get_tostring(const owl_variable *v, const void *val)
    10971072{
    10981073  char **enums;
     
    11001075  char *tostring;
    11011076
     1077  if (val == NULL) {
     1078    return NULL;
     1079  }
    11021080  enums = g_strsplit_set(v->validsettings, ",", 0);
    11031081  nenums = g_strv_length(enums);
    1104   i = owl_variable_get_int(v);
     1082  i = *(const int*)val;
    11051083  if (i<0 || i>=nenums) {
    11061084    g_strfreev(enums);
     
    11141092/* default functions for stringeans */
    11151093
    1116 int owl_variable_string_validate_default(const owl_variable *v, const char *newval) {
     1094int owl_variable_string_validate_default(const struct _owl_variable *v, const void *newval) {
    11171095  if (newval == NULL) return(0);
    11181096  else return (1);
    11191097}
    11201098
    1121 int 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);
     1099int 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);
    11261105  return(0);
    11271106}
    11281107
    1129 int 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 
    1134 CALLER_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 
     1108int owl_variable_string_set_fromstring_default(owl_variable *v, const char *newval) {
     1109  return (v->set_fn(v, newval));
     1110}
     1111
     1112CALLER_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
Note: See TracChangeset for help on using the changeset viewer.