source: variable.c @ 65ad073

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