source: variable.c @ 4692b70

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