source: variable.c @ 5d365f6

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