source: variable.c @ 7e3e00a

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