source: variable.c @ f9c43ae

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