source: variable.c @ 4b660cc

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