source: variable.c @ 61e79a9

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