source: variable.c @ 2fa5eed

barnowl_perlaimdebianrelease-1.4release-1.5release-1.6release-1.7release-1.8release-1.9
Last change on this file since 2fa5eed was 2fa5eed, checked in by Alejandro R. Sedeño <asedeno@mit.edu>, 14 years ago
Fixed regression tests for booleans variables. They were testing a 'string' variable. It looks like this broke when personalbell was tweaked to accept the name of a filter to beep on [r358]. I've changed it to test with rxping. --This line, and those below, will be ignored-- M owl/variable.c
  • Property mode set to 100644
File size: 35.0 KB
Line 
1#include <stdio.h>
2#include <stdlib.h>
3#include <string.h>
4#include <unistd.h>
5#include <ctype.h>
6#include "owl.h"
7
8static const char fileIdent[] = "$Id$";
9
10static int in_regtest = 0;
11
12#define OWLVAR_BOOL(name,default,summary,description) \
13        { name, OWL_VARIABLE_BOOL, NULL, default, "on,off", summary,description, NULL, \
14        NULL, NULL, NULL, NULL, NULL }
15
16#define OWLVAR_BOOL_FULL(name,default,summary,description,validate,set,get) \
17        { name, OWL_VARIABLE_BOOL, NULL, default, "on,off", summary,description, NULL, \
18        validate, set, NULL, get, NULL }
19
20#define OWLVAR_INT(name,default,summary,description) \
21        { name, OWL_VARIABLE_INT, NULL, default, "<int>", summary,description, NULL, \
22        NULL, NULL, NULL, NULL, NULL, NULL }
23
24#define OWLVAR_INT_FULL(name,default,summary,description,validset,validate,set,get) \
25        { name, OWL_VARIABLE_INT, NULL, default, validset, summary,description, NULL, \
26        validate, set, NULL, get, NULL, NULL }
27
28#define OWLVAR_PATH(name,default,summary,description) \
29        { name, OWL_VARIABLE_STRING, default, 0, "<path>", summary,description,  NULL, \
30        NULL, NULL, NULL, NULL, NULL, NULL }
31
32#define OWLVAR_STRING(name,default,summary,description) \
33        { name, OWL_VARIABLE_STRING, default, 0, "<string>", summary,description, NULL, \
34        NULL, NULL, NULL, NULL, NULL, NULL }
35
36#define OWLVAR_STRING_FULL(name,default,summary,description,validate,set,get) \
37        { name, OWL_VARIABLE_STRING, default, 0, "<string>", summary,description, NULL, \
38        validate, set, NULL, get, NULL, NULL }
39
40/* enums are really integers, but where validset is a comma-separated
41 * list of strings which can be specified.  The tokens, starting at 0,
42 * correspond to the values that may be specified. */
43#define OWLVAR_ENUM(name,default,summary,description,validset) \
44        { name, OWL_VARIABLE_INT, NULL, default, validset, summary,description, NULL, \
45        owl_variable_enum_validate, \
46        NULL, owl_variable_enum_set_fromstring, \
47        NULL, owl_variable_enum_get_tostring, \
48        NULL }
49
50#define OWLVAR_ENUM_FULL(name,default,summary,description,validset,validate, set, get) \
51        { name, OWL_VARIABLE_INT, NULL, default, validset, summary,description, NULL, \
52        validate, \
53        set, owl_variable_enum_set_fromstring, \
54        get, owl_variable_enum_get_tostring, \
55        NULL }
56
57static owl_variable variables_to_init[] = {
58
59  OWLVAR_STRING( "personalbell" /* %OwlVarStub */, "off",
60                 "ring the terminal bell when personal messages are received",
61                 "Can be set to 'on', 'off', or the name of a filter which\n"
62                 "messages need to match in order to ring the bell"),
63
64  OWLVAR_BOOL( "bell" /* %OwlVarStub */, 1,
65               "enable / disable the terminal bell", "" ),
66
67  OWLVAR_BOOL_FULL( "debug" /* %OwlVarStub */, OWL_DEBUG,
68                    "whether debugging is enabled",
69                    "If set to 'on', debugging messages are logged to the\n"
70                    "file specified by the debugfile variable.\n",
71                    NULL, owl_variable_debug_set, NULL),
72
73  OWLVAR_BOOL( "startuplogin" /* %OwlVarStub */, 1,
74               "send a login message when owl starts", "" ),
75
76  OWLVAR_BOOL( "shutdownlogout" /* %OwlVarStub */, 1,
77               "send a logout message when owl exits", "" ),
78
79  OWLVAR_BOOL( "rxping" /* %OwlVarStub */, 0,
80               "display received pings", "" ),
81
82  OWLVAR_BOOL( "txping" /* %OwlVarStub */, 1,
83               "send pings", "" ),
84
85  OWLVAR_BOOL( "sepbar_disable" /* %OwlVarStub */, 0,
86               "disable printing information in the seperator bar", "" ),
87
88  OWLVAR_BOOL( "smartstrip" /* %OwlVarStub */, 1,
89               "strip kerberos instance for reply", ""),
90
91  OWLVAR_BOOL( "newlinestrip" /* %OwlVarStub */, 1,
92               "strip leading and trailing newlines", ""),
93
94  OWLVAR_BOOL( "displayoutgoing" /* %OwlVarStub */, 1,
95               "display outgoing messages", "" ),
96
97  OWLVAR_BOOL( "loginsubs" /* %OwlVarStub */, 1,
98               "load logins from .anyone on startup", "" ),
99
100  OWLVAR_BOOL( "logging" /* %OwlVarStub */, 0,
101               "turn personal logging on or off", 
102               "If this is set to on, personal messages are\n"
103               "logged in the directory specified\n"
104               "by the 'logpath' variable.  The filename in that\n"
105               "directory is derived from the sender of the message.\n" ),
106
107  OWLVAR_BOOL( "classlogging" /* %OwlVarStub */, 0,
108               "turn class logging on or off",
109               "If this is set to on, class messages are\n"
110               "logged in the directory specified\n"
111               "by the 'classlogpath' variable.\n" 
112               "The filename in that directory is derived from\n"
113               "the name of the class to which the message was sent.\n" ),
114
115  OWLVAR_ENUM( "loggingdirection" /* %OwlVarStub */, OWL_LOGGING_DIRECTION_BOTH,
116               "specifices which kind of messages should be logged",
117               "Can be one of 'both', 'in', or 'out'.  If 'in' is\n"
118               "selected, only incoming messages are logged, if 'out'\n"
119               "is selected only outgoing messages are logged.  If 'both'\n"
120               "is selected both incoming and outgoing messages are\n"
121               "logged.",
122               "both,in,out"),
123
124  OWLVAR_BOOL( "colorztext" /* %OwlVarStub */, 1,
125               "allow @color() in zephyrs to change color",
126               "Note that only messages received after this variable\n"
127               "is set will be affected." ),
128
129  OWLVAR_BOOL( "fancylines" /* %OwlVarStub */, 1,
130               "Use 'nice' line drawing on the terminal.",
131               "If turned off, dashes, pipes and pluses will be used\n"
132               "to draw lines on the screen.  Useful when the terminal\n"
133               "is causing problems" ),
134
135  OWLVAR_BOOL( "zcrypt" /* %OwlVarStub */, 1,
136               "Do automatic zcrypt processing",
137               "" ),
138
139  OWLVAR_BOOL_FULL( "pseudologins" /* %OwlVarStub */, 0,
140                    "Enable zephyr pseudo logins",
141                    "When this is enabled, Owl will periodically check the zephyr\n"
142                    "location of users in your .anyone file.  If a user is present\n"
143                    "but sent no login message, or a user is not present that sent no\n"
144                    "logout message a pseudo login or logout message wil be created\n",
145                    NULL, owl_variable_pseudologins_set, NULL),
146
147  OWLVAR_BOOL( "ignorelogins" /* %OwlVarStub */, 0,
148               "Enable printing of login notifications",
149               "When this is enabled, Owl will print login and logout notifications\n"
150               "for AIM, zephyr, or other protocols.  If disabled Owl will not print\n"
151               "login or logout notifications.\n"),
152
153  OWLVAR_STRING( "logfilter" /* %OwlVarStub */, "",
154                 "name of a filter controlling which messages to log",
155
156                 "If non empty, any messages matching the given filter will be logged.\n"
157                 "This is a completely separate mechanisim from the other logging\n"
158                 "variables like logging, classlogging, loglogins, loggingdirection,\n"
159                 "etc.  If you want this variable to control all logging, make sure\n"
160                 "all other logging variables are in their default state.\n"),
161
162  OWLVAR_BOOL( "loglogins" /* %OwlVarStub */, 0,
163               "Enable logging of login notifications",
164               "When this is enabled, Owl will login login and logout notifications\n"
165               "for AIM, zephyr, or other protocols.  If disabled Owl will not print\n"
166               "login or logout notifications.\n"),
167
168  OWLVAR_ENUM_FULL( "disable-ctrl-d" /* %OwlVarStub:lockout_ctrld */, 1,
169                    "don't send zephyrs on C-d",
170                    "If set to 'off', C-d won't send a zephyr from the edit\n"
171                    "window.  If set to 'on', C-d will always send a zephyr\n"
172                    "being composed in the edit window.  If set to 'middle',\n"
173                    "C-d will only ever send a zephyr if the cursor is at\n"
174                    "the end of the message being composed.\n\n"
175                    "Note that this works by changing the C-d keybinding\n"
176                    "in the editmulti keymap.\n",
177                    "off,middle,on",
178                    NULL, owl_variable_disable_ctrl_d_set, NULL),
179
180  OWLVAR_BOOL( "_burningears" /* %OwlVarStub:burningears */, 0,
181               "[NOT YET IMPLEMENTED] beep on messages matching patterns", "" ),
182
183  OWLVAR_BOOL( "_summarymode" /* %OwlVarStub:summarymode */, 0,
184               "[NOT YET IMPLEMENTED]", "" ),
185
186  OWLVAR_PATH( "logpath" /* %OwlVarStub */, "~/zlog/people",
187               "path for logging personal zephyrs", 
188               "Specifies a directory which must exist.\n"
189               "Files will be created in the directory for each sender.\n"),
190
191  OWLVAR_PATH( "classlogpath" /* %OwlVarStub:classlogpath */, "~/zlog/class",
192               "path for logging class zephyrs",
193               "Specifies a directory which must exist.\n"
194               "Files will be created in the directory for each class.\n"),
195
196  OWLVAR_PATH( "debug_file" /* %OwlVarStub */, OWL_DEBUG_FILE,
197               "path for logging debug messages when debugging is enabled",
198               "This file will be logged to if 'debug' is set to 'on'.\n"),
199 
200  OWLVAR_PATH( "zsigproc" /* %OwlVarStub:zsigproc */, NULL,
201               "name of a program to run that will generate zsigs",
202               "This program should produce a zsig on stdout when run.\n"
203               "Note that it is important that this program not block.\n" ),
204
205  OWLVAR_PATH( "newmsgproc" /* %OwlVarStub:newmsgproc */, NULL,
206               "name of a program to run when new messages are present",
207               "The named program will be run when owl recevies new.\n"
208               "messages.  It will not be run again until the first\n"
209               "instance exits"),
210
211  OWLVAR_STRING( "zsig" /* %OwlVarStub */, "",
212                 "zephyr signature", 
213                 "If 'zsigproc' is not set, this string will be used\n"
214                 "as a zsig.  If this is also unset, the 'zwrite-signature'\n"
215                 "zephyr variable will be used instead.\n"),
216
217  OWLVAR_STRING( "appendtosepbar" /* %OwlVarStub */, "",
218                 "string to append to the end of the sepbar",
219                 "The sepbar is the bar separating the top and bottom\n"
220                 "of the owl screen.  Any string specified here will\n"
221                 "be displayed on the right of the sepbar\n"),
222
223  OWLVAR_BOOL( "zaway" /* %OwlVarStub */, 0,
224               "turn zaway on or off", "" ),
225
226  OWLVAR_STRING( "zaway_msg" /* %OwlVarStub */, 
227                 OWL_DEFAULT_ZAWAYMSG,
228                 "zaway msg for responding to zephyrs when away", "" ),
229
230  OWLVAR_STRING( "zaway_msg_default" /* %OwlVarStub */, 
231                 OWL_DEFAULT_ZAWAYMSG,
232                 "default zaway message", "" ),
233
234  OWLVAR_BOOL_FULL( "aaway" /* %OwlVarStub */, 0,
235                    "Set AIM away status",
236                    "",
237                    NULL, owl_variable_aaway_set, NULL),
238
239  OWLVAR_STRING( "aaway_msg" /* %OwlVarStub */, 
240                 OWL_DEFAULT_AAWAYMSG,
241                 "AIM away msg for responding when away", "" ),
242
243  OWLVAR_STRING( "aaway_msg_default" /* %OwlVarStub */, 
244                 OWL_DEFAULT_AAWAYMSG,
245                 "default AIM away message", "" ),
246
247  OWLVAR_STRING( "view_home" /* %OwlVarStub */, "all",
248                 "home view to switch to after 'X' and 'V'", 
249                 "SEE ALSO: view, filter\n" ),
250
251  OWLVAR_STRING( "alert_filter" /* %OwlVarStub */, "none",
252                 "filter on which to trigger alert actions",
253                 "" ),
254
255  OWLVAR_STRING( "alert_action" /* %OwlVarStub */, "nop",
256                 "owl command to execute for alert actions",
257                 "" ),
258
259  OWLVAR_STRING_FULL( "tty" /* %OwlVarStub */, "", "tty name for zephyr location", "",
260                      NULL, owl_variable_tty_set, NULL),
261
262  OWLVAR_STRING( "default_style" /* %OwlVarStub */, "__unspecified__",
263                 "name of the default formatting style",
264                 "This sets the default message formatting style.\n"
265                 "Styles may be created with the 'style' command.\n"
266                 "Some built-in styles include:\n"
267                 "   default  - the default owl formatting\n"
268                 "   basic    - simple formatting\n"
269                 "   oneline  - one line per-message\n"
270                 "   perl     - legacy perl interface\n"
271                 "\nSEE ALSO: style, show styles, view -s <style>\n"
272                 ),
273
274
275  OWLVAR_INT(    "edit:maxfillcols" /* %OwlVarStub:edit_maxfillcols */, 70,
276                 "maximum number of columns for M-q to fill text to",
277                 "This specifies the maximum number of columns for M-q\n"
278                 "to fill text to.  If set to 0, ther will be no maximum\n"
279                 "limit.  In all cases, the current width of the screen\n"
280                 "will also be taken into account.  It will be used instead\n"
281                 "if it is narrower than the maximum, or if this\n"
282                 "is set to 0.\n" ),
283
284  OWLVAR_INT(    "edit:maxwrapcols" /* %OwlVarStub:edit_maxwrapcols */, 0,
285                 "maximum number of columns for line-wrapping",
286                 "This specifies the maximum number of columns for\n"
287                 "auto-line-wrapping.  If set to 0, ther will be no maximum\n"
288                 "limit.  In all cases, the current width of the screen\n"
289                 "will also be taken into account.  It will be used instead\n"
290                 "if it is narrower than the maximum, or if this\n"
291                 "is set to 0.\n\n"
292                 "It is recommended that outgoing messages be no wider\n"
293                 "than 60 columns, as a courtesy to recipients.\n"),
294
295  OWLVAR_INT( "aim_ignorelogin_timer" /* %OwlVarStub */, 15,
296              "number of seconds after AIM login to ignore login messages",
297              "This specifies the number of seconds to wait after an\n"
298              "AIM login before allowing the recipt of AIM login notifications.\n"
299              "By default this is set to 15.  If you would like to view login\n"
300              "notifications of buddies as soon as you login, set it to 0 instead."),
301
302             
303  OWLVAR_INT_FULL( "typewinsize" /* %OwlVarStub:typwin_lines */, 
304                   OWL_TYPWIN_SIZE,
305                  "number of lines in the typing window", 
306                   "This specifies the height of the window at the\n"
307                   "bottom of the screen where commands are entered\n"
308                   "and where messages are composed.\n",
309                   "int > 0",
310                   owl_variable_int_validate_gt0,
311                   owl_variable_typewinsize_set,
312                   NULL /* use default for get */
313                   ),
314
315  OWLVAR_ENUM( "scrollmode" /* %OwlVarStub */, OWL_SCROLLMODE_NORMAL,
316               "how to scroll up and down",
317               "This controls how the screen is scrolled as the\n"
318               "cursor moves between messages being displayed.\n"
319               "The following modes are supported:\n\n"
320               "   normal      - This is the owl default.  Scrolling happens\n"
321               "                 when it needs to, and an attempt is made to\n"
322               "                 keep the current message roughly near\n"
323               "                 the middle of the screen.\n"
324               "   top         - The current message will always be the\n"
325               "                 the top message displayed.\n"
326               "   neartop     - The current message will be one down\n"
327               "                 from the top message displayed,\n"
328               "                 where possible.\n"
329               "   center      - An attempt is made to keep the current\n"
330               "                 message near the center of the screen.\n"
331               "   paged       - The top message displayed only changes\n"
332               "                 when user moves the cursor to the top\n"
333               "                 or bottom of the screen.  When it moves,\n"
334               "                 the screen will be paged up or down and\n"
335               "                 the cursor will be near the top or\n"
336               "                 the bottom.\n"
337               "   pagedcenter - The top message displayed only changes\n"
338               "                 when user moves the cursor to the top\n"
339               "                 or bottom of the screen.  When it moves,\n"
340               "                 the screen will be paged up or down and\n"
341               "                 the cursor will be near the center.\n",
342               "normal,top,neartop,center,paged,pagedcenter" ),
343
344  OWLVAR_ENUM( "webbrowser" /* %OwlVarStub */, OWL_WEBBROWSER_NETSCAPE,
345               "web browser to use to launch URLs",
346               "When the 'w' key is pressed, this browser is used\n"
347               "to display the requested URL.\n",
348               "none,netscape,galeon,opera" ),
349
350
351  OWLVAR_BOOL( "_followlast" /* %OwlVarStub */, 0,
352               "enable automatic following of the last zephyr",
353               "If the cursor is at the last message, it will\n"
354               "continue to follow the last message if this is set.\n"
355               "Note that this is currently risky as you might accidentally\n"
356               "delete a message right as it came in.\n" ),
357
358  /* This MUST be last... */
359  { NULL, 0, NULL, 0, NULL, NULL, NULL, NULL,
360    NULL, NULL, NULL, NULL, NULL, NULL }
361
362};
363
364/**************************************************************************/
365/*********************** SPECIFIC TO VARIABLES ****************************/
366/**************************************************************************/
367
368
369/* commonly useful */
370
371int owl_variable_int_validate_gt0(owl_variable *v, void *newval)
372{
373  if (newval == NULL) return(0);
374  else if (*(int*)newval < 1) return(0);
375  else return (1);
376}
377
378int owl_variable_int_validate_positive(owl_variable *v, void *newval)
379{
380  if (newval == NULL) return(0);
381  else if (*(int*)newval < 0) return(0);
382  else return (1);
383}
384
385/* typewinsize */
386int owl_variable_typewinsize_set(owl_variable *v, void *newval)
387{
388  int rv;
389  rv = owl_variable_int_set_default(v, newval);
390  if (0 == rv) owl_function_resize();
391  return(rv);
392}
393
394/* debug (cache value in g->debug) */
395int owl_variable_debug_set(owl_variable *v, void *newval)
396{
397  if (newval && (*(int*)newval == 1 || *(int*)newval == 0)) {
398    g.debug = *(int*)newval;
399  }
400  return owl_variable_bool_set_default(v, newval);
401}
402
403/* When 'aaway' is changed, need to notify the AIM server */
404int owl_variable_aaway_set(owl_variable *v, void *newval)
405{
406  if (newval) {
407    if (*(int*)newval == 1) {
408      owl_aim_set_awaymsg(owl_global_get_aaway_msg(&g));
409    } else if (*(int*)newval == 0) {
410      owl_aim_set_awaymsg("");
411    }
412  }
413  return owl_variable_bool_set_default(v, newval);
414}
415
416int owl_variable_pseudologins_set(owl_variable *v, void *newval)
417{
418  if (newval) {
419    if (*(int*)newval == 1) {
420      owl_function_zephyr_buddy_check(0);
421    }
422  }
423  return owl_variable_bool_set_default(v, newval);
424}
425
426/* note that changing the value of this will clobber
427 * any user setting of this */
428int owl_variable_disable_ctrl_d_set(owl_variable *v, void *newval)
429{
430
431  if (in_regtest) return owl_variable_int_set_default(v, newval);
432
433  if (newval && !owl_context_is_startup(owl_global_get_context(&g))) {
434    if (*(int*)newval == 2) {
435      owl_function_command_norv("bindkey editmulti C-d command edit:delete-next-char");
436    } else if (*(int*)newval == 1) {
437      owl_function_command_norv("bindkey editmulti C-d command editmulti:done-or-delete");
438    } else {
439      owl_function_command_norv("bindkey editmulti C-d command editmulti:done");
440    }
441  } 
442  return owl_variable_int_set_default(v, newval); 
443}
444
445int owl_variable_tty_set(owl_variable *v, void *newval)
446{
447  owl_zephyr_set_locationinfo(owl_global_get_hostname(&g), newval);
448  return(owl_variable_string_set_default(v, newval));
449}
450
451
452/**************************************************************************/
453/****************************** GENERAL ***********************************/
454/**************************************************************************/
455
456int owl_variable_dict_setup(owl_vardict *vd) {
457  owl_variable *cur;
458  if (owl_dict_create(vd)) return(-1);
459  for (cur = variables_to_init; cur->name != NULL; cur++) {
460    switch (cur->type) {
461    case OWL_VARIABLE_OTHER:
462      cur->set_fn(cur, cur->pval_default);
463      break;
464    case OWL_VARIABLE_STRING:
465      if (!cur->validate_fn) 
466        cur->validate_fn = owl_variable_string_validate_default;
467      if (!cur->set_fn) 
468        cur->set_fn = owl_variable_string_set_default;
469      if (!cur->set_fromstring_fn) 
470        cur->set_fromstring_fn = owl_variable_string_set_fromstring_default;
471      if (!cur->get_fn) 
472        cur->get_fn = owl_variable_get_default;
473      if (!cur->get_tostring_fn) 
474        cur->get_tostring_fn = owl_variable_string_get_tostring_default;     
475      if (!cur->free_fn) 
476        cur->free_fn = owl_variable_free_default;
477      cur->set_fn(cur, cur->pval_default);
478      break;
479    case OWL_VARIABLE_BOOL:
480      if (!cur->validate_fn) 
481        cur->validate_fn = owl_variable_bool_validate_default;
482      if (!cur->set_fn) 
483        cur->set_fn = owl_variable_bool_set_default;
484      if (!cur->set_fromstring_fn) 
485        cur->set_fromstring_fn = owl_variable_bool_set_fromstring_default;
486      if (!cur->get_fn) 
487        cur->get_fn = owl_variable_get_default;
488      if (!cur->get_tostring_fn) 
489        cur->get_tostring_fn = owl_variable_bool_get_tostring_default;     
490      if (!cur->free_fn) 
491        cur->free_fn = owl_variable_free_default;
492      cur->val = owl_malloc(sizeof(int));
493      cur->set_fn(cur, &cur->ival_default);
494      break;
495    case OWL_VARIABLE_INT:
496      if (!cur->validate_fn) 
497        cur->validate_fn = owl_variable_int_validate_default;
498      if (!cur->set_fn) 
499        cur->set_fn = owl_variable_int_set_default;
500      if (!cur->set_fromstring_fn) 
501        cur->set_fromstring_fn = owl_variable_int_set_fromstring_default;
502      if (!cur->get_fn) 
503        cur->get_fn = owl_variable_get_default;
504      if (!cur->get_tostring_fn) 
505        cur->get_tostring_fn = owl_variable_int_get_tostring_default;     
506      if (!cur->free_fn) 
507        cur->free_fn = owl_variable_free_default;
508      cur->val = owl_malloc(sizeof(int));
509      cur->set_fn(cur, &cur->ival_default);
510      break;
511    default:
512      fprintf(stderr, "owl_variable_setup: invalid variable type\n");
513      return(-2);
514    }
515    owl_dict_insert_element(vd, cur->name, (void*)cur, NULL);
516  }
517  return 0;
518}
519
520void owl_variable_dict_free(owl_vardict *d) {
521  owl_dict_free_all(d, (void(*)(void*))owl_variable_free);
522}
523
524/* free the list with owl_variable_dict_namelist_free */
525void owl_variable_dict_get_names(owl_vardict *d, owl_list *l) {
526  owl_dict_get_keys(d, l);
527}
528
529void owl_variable_dict_namelist_free(owl_list *l) {
530  owl_list_free_all(l, owl_free);
531}
532
533void owl_variable_free(owl_variable *v) {
534  if (v->free_fn) v->free_fn(v);
535}
536
537
538char *owl_variable_get_description(owl_variable *v) {
539  return v->description;
540}
541
542char *owl_variable_get_summary(owl_variable *v) {
543  return v->summary;
544}
545
546char *owl_variable_get_validsettings(owl_variable *v) {
547  if (v->validsettings) {
548    return v->validsettings;
549  } else {
550    return "";
551  }
552}
553
554/* functions for getting and setting variable values */
555
556/* returns 0 on success, prints a status msg if msg is true */
557int owl_variable_set_fromstring(owl_vardict *d, char *name, char *value, int msg, int requirebool) {
558  owl_variable *v;
559  char buff2[1024];
560  if (!name) return(-1);
561  v = owl_dict_find_element(d, name);
562  if (v == NULL) {
563    if (msg) owl_function_error("Unknown variable %s", name);
564    return -1;
565  }
566  if (!v->set_fromstring_fn) {
567    if (msg) owl_function_error("Variable %s is read-only", name);
568    return -1;   
569  }
570  if (requirebool && v->type!=OWL_VARIABLE_BOOL) {
571    if (msg) owl_function_error("Variable %s is not a boolean", name);
572    return -1;   
573  }
574  if (0 != v->set_fromstring_fn(v, value)) {
575    if (msg) owl_function_error("Unable to set %s (must be %s)", name, 
576                                  owl_variable_get_validsettings(v));
577    return -1;
578  }
579  if (msg && v->get_tostring_fn) {
580    v->get_tostring_fn(v, buff2, 1024, v->val);
581    owl_function_makemsg("%s = '%s'", name, buff2);
582  }   
583  return 0;
584}
585 
586int owl_variable_set_string(owl_vardict *d, char *name, char *newval) {
587  owl_variable *v;
588  if (!name) return(-1);
589  v = owl_dict_find_element(d, name);
590  if (v == NULL || !v->set_fn) return(-1);
591  if (v->type!=OWL_VARIABLE_STRING) return(-1);
592  return v->set_fn(v, (void*)newval);
593}
594 
595int owl_variable_set_int(owl_vardict *d, char *name, int newval) {
596  owl_variable *v;
597  if (!name) return(-1);
598  v = owl_dict_find_element(d, name);
599  if (v == NULL || !v->set_fn) return(-1);
600  if (v->type!=OWL_VARIABLE_INT && v->type!=OWL_VARIABLE_BOOL) return(-1);
601  return v->set_fn(v, &newval);
602}
603 
604int owl_variable_set_bool_on(owl_vardict *d, char *name) {
605  return owl_variable_set_int(d,name,1);
606}
607
608int owl_variable_set_bool_off(owl_vardict *d, char *name) {
609  return owl_variable_set_int(d,name,0);
610}
611
612int owl_variable_get_tostring(owl_vardict *d, char *name, char *buf, int bufsize) {
613  owl_variable *v;
614  if (!name) return(-1);
615  v = owl_dict_find_element(d, name);
616  if (v == NULL || !v->get_tostring_fn) return(-1);
617  return v->get_tostring_fn(v, buf, bufsize, v->val);
618}
619
620int owl_variable_get_default_tostring(owl_vardict *d, char *name, char *buf, int bufsize) {
621  owl_variable *v;
622  if (!name) return(-1);
623  v = owl_dict_find_element(d, name);
624  if (v == NULL || !v->get_tostring_fn) return(-1);
625  if (v->type == OWL_VARIABLE_INT || v->type == OWL_VARIABLE_BOOL) {
626    return v->get_tostring_fn(v, buf, bufsize, &(v->ival_default));
627  } else {
628    return v->get_tostring_fn(v, buf, bufsize, v->pval_default);
629  }
630}
631
632/* returns a reference */
633void *owl_variable_get(owl_vardict *d, char *name, int require_type) {
634  owl_variable *v;
635  if (!name) return(NULL);
636  v = owl_dict_find_element(d, name);
637  if (v == NULL || !v->get_fn || v->type != require_type) return(NULL);
638  return v->get_fn(v);
639}
640
641/* returns a reference */
642char *owl_variable_get_string(owl_vardict *d, char *name) {
643  return (char*)owl_variable_get(d,name, OWL_VARIABLE_STRING);
644}
645
646/* returns a reference */
647void *owl_variable_get_other(owl_vardict *d, char *name) {
648  return (char*)owl_variable_get(d,name, OWL_VARIABLE_OTHER);
649}
650
651int owl_variable_get_int(owl_vardict *d, char *name) {
652  int *pi;
653  pi = (int*)owl_variable_get(d,name,OWL_VARIABLE_INT);
654  if (!pi) return(-1);
655  return(*pi);
656}
657
658int owl_variable_get_bool(owl_vardict *d, char *name) {
659  int *pi;
660  pi = (int*)owl_variable_get(d,name,OWL_VARIABLE_BOOL);
661  if (!pi) return(-1);
662  return(*pi);
663}
664
665void owl_variable_describe(owl_vardict *d, char *name, owl_fmtext *fm) {
666  char defaultbuf[50];
667  char buf[1024];
668  int buflen = 1023;
669  owl_variable *v;
670
671  if (!name
672      || (v = owl_dict_find_element(d, name)) == NULL 
673      || !v->get_fn) {
674    snprintf(buf, buflen, "     No such variable '%s'\n", name);     
675    owl_fmtext_append_normal(fm, buf);
676    return;
677  }
678  if (v->type == OWL_VARIABLE_INT || v->type == OWL_VARIABLE_BOOL) {
679    v->get_tostring_fn(v, defaultbuf, 50, &(v->ival_default));
680  } else {
681    v->get_tostring_fn(v, defaultbuf, 50, v->pval_default);
682  }
683  snprintf(buf, buflen, OWL_TABSTR "%-20s - %s (default: '%s')\n", 
684                  v->name, 
685                  owl_variable_get_summary(v), defaultbuf);
686  owl_fmtext_append_normal(fm, buf);
687}
688
689void owl_variable_get_help(owl_vardict *d, char *name, owl_fmtext *fm) {
690  char buff[1024];
691  int bufflen = 1023;
692  owl_variable *v;
693
694  if (!name
695      || (v = owl_dict_find_element(d, name)) == NULL 
696      || !v->get_fn) {
697    owl_fmtext_append_normal(fm, "No such variable...\n");
698    return;
699  }
700
701  owl_fmtext_append_bold(fm, "OWL VARIABLE\n\n");
702  owl_fmtext_append_normal(fm, OWL_TABSTR);
703  owl_fmtext_append_normal(fm, name);
704  owl_fmtext_append_normal(fm, " - ");
705  owl_fmtext_append_normal(fm, v->summary);
706  owl_fmtext_append_normal(fm, "\n\n");
707
708  owl_fmtext_append_normal(fm, "Current:        ");
709  owl_variable_get_tostring(d, name, buff, bufflen);
710  owl_fmtext_append_normal(fm, buff);
711  owl_fmtext_append_normal(fm, "\n\n");
712
713
714  if (v->type == OWL_VARIABLE_INT || v->type == OWL_VARIABLE_BOOL) {
715    v->get_tostring_fn(v, buff, bufflen, &(v->ival_default));
716  } else {
717    v->get_tostring_fn(v, buff, bufflen, v->pval_default);
718  }
719  owl_fmtext_append_normal(fm, "Default:        ");
720  owl_fmtext_append_normal(fm, buff);
721  owl_fmtext_append_normal(fm, "\n\n");
722
723  owl_fmtext_append_normal(fm, "Valid Settings: ");
724  owl_fmtext_append_normal(fm, owl_variable_get_validsettings(v));
725  owl_fmtext_append_normal(fm, "\n\n");
726
727  if (v->description && *v->description) {
728    owl_fmtext_append_normal(fm, "Description:\n");
729    owl_fmtext_append_normal(fm, owl_variable_get_description(v));
730    owl_fmtext_append_normal(fm, "\n\n");
731  }
732}
733
734
735
736
737/**************************************************************************/
738/*********************** GENERAL TYPE-SPECIFIC ****************************/
739/**************************************************************************/
740
741/* default common functions */
742
743void *owl_variable_get_default(owl_variable *v) {
744  return v->val;
745}
746
747void owl_variable_free_default(owl_variable *v) {
748  if (v->val) owl_free(v->val);
749}
750
751/* default functions for booleans */
752
753int owl_variable_bool_validate_default(owl_variable *v, void *newval) {
754  if (newval == NULL) return(0);
755  else if (*(int*)newval==1 || *(int*)newval==0) return(1);
756  else return (0);
757}
758
759int owl_variable_bool_set_default(owl_variable *v, void *newval) {
760  if (v->validate_fn) {
761    if (!v->validate_fn(v, newval)) return(-1);
762  }
763  *(int*)v->val = *(int*)newval;
764  return(0);
765}
766
767int owl_variable_bool_set_fromstring_default(owl_variable *v, char *newval) {
768  int i;
769  if (!strcmp(newval, "on")) i=1;
770  else if (!strcmp(newval, "off")) i=0;
771  else return(-1);
772  return (v->set_fn(v, &i));
773}
774
775int owl_variable_bool_get_tostring_default(owl_variable *v, char* buf, int bufsize, void *val) {
776  if (val == NULL) {
777    snprintf(buf, bufsize, "<null>");
778    return -1;
779  } else if (*(int*)val == 0) {
780    snprintf(buf, bufsize, "off");
781    return 0;
782  } else if (*(int*)val == 1) {
783    snprintf(buf, bufsize, "on");
784    return 0;
785  } else {
786    snprintf(buf, bufsize, "<invalid>");
787    return -1;
788  }
789}
790
791/* default functions for integers */
792
793int owl_variable_int_validate_default(owl_variable *v, void *newval) {
794  if (newval == NULL) return(0);
795  else return (1);
796}
797
798int owl_variable_int_set_default(owl_variable *v, void *newval) {
799  if (v->validate_fn) {
800    if (!v->validate_fn(v, newval)) return(-1);
801  }
802  *(int*)v->val = *(int*)newval;
803  return(0);
804}
805
806int owl_variable_int_set_fromstring_default(owl_variable *v, char *newval) {
807  int i;
808  char *ep = "x";
809  i = strtol(newval, &ep, 10);
810  if (*ep || ep==newval) return(-1);
811  return (v->set_fn(v, &i));
812}
813
814int owl_variable_int_get_tostring_default(owl_variable *v, char* buf, int bufsize, void *val) {
815  if (val == NULL) {
816    snprintf(buf, bufsize, "<null>");
817    return -1;
818  } else {
819    snprintf(buf, bufsize, "%d", *(int*)val);
820    return 0;
821  } 
822}
823
824/* default functions for enums (a variant of integers) */
825
826int owl_variable_enum_validate(owl_variable *v, void *newval) { 
827  char **enums;
828  int nenums, val;
829  if (newval == NULL) return(0);
830  enums = atokenize(v->validsettings, ",", &nenums);
831  if (enums == NULL) return(0);
832  atokenize_free(enums, nenums);
833  val = *(int*)newval;
834  if (val < 0 || val >= nenums) {
835    return(0);
836  }
837  return(1);
838}
839
840int owl_variable_enum_set_fromstring(owl_variable *v, char *newval) {
841  char **enums;
842  int nenums, i, val=-1;
843  if (newval == NULL) return(-1);
844  enums = atokenize(v->validsettings, ",", &nenums);
845  if (enums == NULL) return(-1);
846  for (i=0; i<nenums; i++) {
847    if (0==strcmp(newval, enums[i])) {
848      val = i;
849    }
850  }
851  atokenize_free(enums, nenums);
852  if (val == -1) return(-1);
853  return (v->set_fn(v, &val));
854}
855
856int owl_variable_enum_get_tostring(owl_variable *v, char* buf, int bufsize, void *val) {
857  char **enums;
858  int nenums, i;
859
860  if (val == NULL) {
861    snprintf(buf, bufsize, "<null>");
862    return -1;
863  }
864  enums = atokenize(v->validsettings, ",", &nenums);
865  i = *(int*)val;
866  if (i<0 || i>=nenums) {
867    snprintf(buf, bufsize, "<invalid:%d>",i);
868    atokenize_free(enums, nenums);
869    return(-1);
870  }
871  snprintf(buf, bufsize, "%s", enums[i]);
872  return 0;
873}
874
875/* default functions for stringeans */
876
877int owl_variable_string_validate_default(struct _owl_variable *v, void *newval) {
878  if (newval == NULL) return(0);
879  else return (1);
880}
881
882int owl_variable_string_set_default(owl_variable *v, void *newval) {
883  if (v->validate_fn) {
884    if (!v->validate_fn(v, newval)) return(-1);
885  }
886  if (v->val) owl_free(v->val);
887  v->val = owl_strdup(newval);
888  return(0);
889}
890
891int owl_variable_string_set_fromstring_default(owl_variable *v, char *newval) {
892  return (v->set_fn(v, newval));
893}
894
895int owl_variable_string_get_tostring_default(owl_variable *v, char* buf, int bufsize, void *val) {
896  if (val == NULL) {
897    snprintf(buf, bufsize, "<null>");
898    return -1;
899  } else {
900    snprintf(buf, bufsize, "%s", (char*)val);
901    return 0;
902  }
903}
904
905
906
907/**************************************************************************/
908/************************* REGRESSION TESTS *******************************/
909/**************************************************************************/
910
911#ifdef OWL_INCLUDE_REG_TESTS
912
913#include "test.h"
914
915int owl_variable_regtest(void) {
916  owl_vardict vd;
917  int numfailed=0;
918  char buf[1024];
919
920  in_regtest = 1;
921
922  printf("BEGIN testing owl_variable\n");
923  FAIL_UNLESS("setup", 0==owl_variable_dict_setup(&vd));
924
925  FAIL_UNLESS("get bool", 0==owl_variable_get_bool(&vd,"rxping"));
926  FAIL_UNLESS("get bool (no such)", -1==owl_variable_get_bool(&vd,"mumble"));
927  FAIL_UNLESS("get bool as string 1", 0==owl_variable_get_tostring(&vd,"rxping", buf, 1024));
928  FAIL_UNLESS("get bool as string 2", 0==strcmp(buf,"off"));
929  FAIL_UNLESS("set bool 1", 0==owl_variable_set_bool_on(&vd,"rxping"));
930  FAIL_UNLESS("get bool 2", 1==owl_variable_get_bool(&vd,"rxping"));
931  FAIL_UNLESS("set bool 3", 0==owl_variable_set_fromstring(&vd,"rxping","off",0,0));
932  FAIL_UNLESS("get bool 4", 0==owl_variable_get_bool(&vd,"rxping"));
933  FAIL_UNLESS("set bool 5", -1==owl_variable_set_fromstring(&vd,"rxping","xxx",0,0));
934  FAIL_UNLESS("get bool 6", 0==owl_variable_get_bool(&vd,"rxping"));
935
936
937  FAIL_UNLESS("get string", 0==strcmp("~/zlog/people", owl_variable_get_string(&vd,"logpath")));
938  FAIL_UNLESS("set string 7", 0==owl_variable_set_string(&vd,"logpath","whee"));
939  FAIL_UNLESS("get string", 0==strcmp("whee", owl_variable_get_string(&vd,"logpath")));
940
941  FAIL_UNLESS("get int", 8==owl_variable_get_int(&vd,"typewinsize"));
942  FAIL_UNLESS("get int (no such)", -1==owl_variable_get_int(&vd,"mmble"));
943  FAIL_UNLESS("get int as string 1", 0==owl_variable_get_tostring(&vd,"typewinsize", buf, 1024));
944  FAIL_UNLESS("get int as string 2", 0==strcmp(buf,"8"));
945  FAIL_UNLESS("set int 1", 0==owl_variable_set_int(&vd,"typewinsize",12));
946  FAIL_UNLESS("get int 2", 12==owl_variable_get_int(&vd,"typewinsize"));
947  FAIL_UNLESS("set int 1b", -1==owl_variable_set_int(&vd,"typewinsize",-3));
948  FAIL_UNLESS("get int 2b", 12==owl_variable_get_int(&vd,"typewinsize"));
949  FAIL_UNLESS("set int 3", 0==owl_variable_set_fromstring(&vd,"typewinsize","9",0,0));
950  FAIL_UNLESS("get int 4", 9==owl_variable_get_int(&vd,"typewinsize"));
951  FAIL_UNLESS("set int 5", -1==owl_variable_set_fromstring(&vd,"typewinsize","xxx",0,0));
952  FAIL_UNLESS("set int 6", -1==owl_variable_set_fromstring(&vd,"typewinsize","",0,0));
953  FAIL_UNLESS("get int 7", 9==owl_variable_get_int(&vd,"typewinsize"));
954
955  FAIL_UNLESS("get enum", OWL_WEBBROWSER_NETSCAPE==owl_variable_get_int(&vd,"webbrowser"));
956  FAIL_UNLESS("get enum as string 1", 0==owl_variable_get_tostring(&vd,"webbrowser", buf, 1024));
957  FAIL_UNLESS("get enum as string 2", 0==strcmp(buf,"netscape"));
958  FAIL_UNLESS("set enum 1", 0==owl_variable_set_int(&vd,"webbrowser",OWL_WEBBROWSER_GALEON));
959  FAIL_UNLESS("get enum 2", OWL_WEBBROWSER_GALEON==owl_variable_get_int(&vd,"webbrowser"));
960  FAIL_UNLESS("set enum 1b", -1==owl_variable_set_int(&vd,"webbrowser",-3));
961  FAIL_UNLESS("set enum 1b", -1==owl_variable_set_int(&vd,"webbrowser",209));
962  FAIL_UNLESS("get enum 2b", OWL_WEBBROWSER_GALEON==owl_variable_get_int(&vd,"webbrowser"));
963  FAIL_UNLESS("set enum 3", 0==owl_variable_set_fromstring(&vd,"webbrowser","none",0,0));
964  FAIL_UNLESS("get enum 4", OWL_WEBBROWSER_NONE==owl_variable_get_int(&vd,"webbrowser"));
965  FAIL_UNLESS("set enum 5", 0==owl_variable_set_fromstring(&vd,"webbrowser","netscape",0,0));
966  FAIL_UNLESS("get enum 6", OWL_WEBBROWSER_NETSCAPE==owl_variable_get_int(&vd,"webbrowser"));
967  FAIL_UNLESS("set enum 7", -1==owl_variable_set_fromstring(&vd,"webbrowser","xxx",0,0));
968  FAIL_UNLESS("set enum 8", -1==owl_variable_set_fromstring(&vd,"webbrowser","",0,0));
969  FAIL_UNLESS("set enum 9", -1==owl_variable_set_fromstring(&vd,"webbrowser","netscapey",0,0));
970  FAIL_UNLESS("get enum 10", OWL_WEBBROWSER_NETSCAPE==owl_variable_get_int(&vd,"webbrowser"));
971
972
973
974  owl_variable_dict_free(&vd);
975
976  if (numfailed) printf("*** WARNING: failures encountered with owl_variable\n");
977  printf("END testing owl_variable (%d failures)\n", numfailed);
978  return(numfailed);
979}
980
981
982#endif /* OWL_INCLUDE_REG_TESTS */
Note: See TracBrowser for help on using the repository browser.