source: variable.c @ 700c712

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