source: variable.c @ 3038d13

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