1 /* This file is part of GDBM, the GNU data base manager.
2 Copyright (C) 1990, 1991, 1993, 2007, 2011, 2013 Free Software Foundation,
5 GDBM is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 3, or (at your option)
10 GDBM is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with GDBM. If not, see <http://www.gnu.org/licenses/>. */
20 #define VARF_DFL 0x00 /* Default flags -- everything disabled */
21 #define VARF_SET 0x01 /* Variable is set */
22 #define VARF_INIT 0x02 /* Variable is initialized */
23 #define VARF_PROT 0x04 /* Variable is protected, i.e. cannot be unset */
24 #define VARF_OCTAL 0x08 /* For integer variables -- use octal base */
26 #define VAR_IS_SET(v) ((v)->flags & (VARF_SET|VARF_INIT))
41 int (*hook) (struct variable *, union value *);
44 static int open_hook (struct variable *, union value *);
46 static struct variable vartab[] = {
47 /* Top-level prompt */
48 { "ps1", VART_STRING, VARF_INIT, { "%p>%_" } },
49 /* Second-level prompt (used within "def" block) */
50 { "ps2", VART_STRING, VARF_INIT, { "%_>%_" } },
51 /* This delimits array members */
52 { "delim1", VART_STRING, VARF_INIT|VARF_PROT, { "," } },
53 /* This delimits structure members */
54 { "delim2", VART_STRING, VARF_INIT|VARF_PROT, { "," } },
55 { "confirm", VART_BOOL, VARF_INIT, { num: 1 } },
56 { "cachesize", VART_INT, VARF_DFL },
57 { "blocksize", VART_INT, VARF_DFL },
58 { "open", VART_STRING, VARF_DFL, { NULL }, open_hook },
59 { "lock", VART_BOOL, VARF_INIT, { num: 1 } },
60 { "mmap", VART_BOOL, VARF_INIT, { num: 1 } },
61 { "sync", VART_BOOL, VARF_INIT, { num: 0 } },
62 { "filemode", VART_INT, VARF_INIT|VARF_OCTAL|VARF_PROT, { num: 0644 } },
63 { "pager", VART_STRING, VARF_DFL },
64 { "quiet", VART_BOOL, VARF_DFL },
69 open_hook (struct variable *var, union value *v)
75 { "newdb", GDBM_NEWDB },
76 { "wrcreat", GDBM_WRCREAT },
77 { "rw", GDBM_WRCREAT },
78 { "reader", GDBM_READER },
79 { "readonly", GDBM_READER },
85 return VAR_ERR_BADVALUE;
87 for (i = 0; trans[i].s; i++)
88 if (strcmp (trans[i].s, v->string) == 0)
90 open_mode = trans[i].t;
94 return VAR_ERR_BADVALUE;
97 static struct variable *
98 varfind (const char *name)
102 for (vp = vartab; vp->name; vp++)
103 if (strcmp (vp->name, name) == 0)
109 typedef int (*setvar_t) (union value *, void *, int);
112 s2s (union value *vp, void *val, int flags)
114 vp->string = estrdup (val);
119 b2s (union value *vp, void *val, int flags)
121 vp->string = estrdup (*(int*)val ? "true" : "false");
126 i2s (union value *vp, void *val, int flags)
129 snprintf (buf, sizeof buf, "%d", *(int*)val);
130 vp->string = estrdup (buf);
135 s2b (union value *vp, void *val, int flags)
137 static char *trueval[] = { "on", "true", "yes", NULL };
138 static char *falseval[] = { "off", "false", "no", NULL };
143 for (i = 0; trueval[i]; i++)
144 if (strcasecmp (trueval[i], val) == 0)
150 for (i = 0; falseval[i]; i++)
151 if (strcasecmp (falseval[i], val) == 0)
157 n = strtoul (val, &p, 0);
159 return VAR_ERR_BADTYPE;
165 s2i (union value *vp, void *val, int flags)
168 int n = strtoul (val, &p, (flags & VARF_OCTAL) ? 8 : 10);
171 return VAR_ERR_BADTYPE;
178 b2b (union value *vp, void *val, int flags)
180 vp->bool = !!*(int*)val;
185 b2i (union value *vp, void *val, int flags)
187 vp->num = *(int*)val;
192 i2i (union value *vp, void *val, int flags)
194 vp->num = *(int*)val;
199 i2b (union value *vp, void *val, int flags)
201 vp->bool = *(int*)val;
205 static setvar_t setvar[3][3] = {
207 /* s */ { s2s, b2s, i2s },
208 /* b */ { s2b, b2b, i2b },
209 /* i */ { s2i, b2i, i2i }
213 variable_set (const char *name, int type, void *val)
215 struct variable *vp = varfind (name);
217 union value v, *valp;
220 return VAR_ERR_NOTDEF;
224 memset (&v, 0, sizeof (v));
225 rc = setvar[vp->type][type] (&v, val, vp->flags);
232 if (vp->flags & VARF_PROT)
233 return VAR_ERR_BADVALUE;
237 if (vp->hook && (rc = vp->hook (vp, valp)) != VAR_OK)
240 if (vp->type == VART_STRING && (vp->flags & VARF_SET))
245 vp->flags &= (VARF_INIT|VARF_SET);
250 vp->flags &= ~VARF_INIT;
251 vp->flags |= VARF_SET;
258 variable_unset (const char *name)
260 struct variable *vp = varfind (name);
264 return VAR_ERR_NOTDEF;
265 if (vp->flags & VARF_PROT)
266 return VAR_ERR_BADVALUE;
268 if (vp->hook && (rc = vp->hook (vp, NULL)) != VAR_OK)
271 vp->flags &= ~(VARF_INIT|VARF_SET);
277 variable_get (const char *name, int type, void **val)
279 struct variable *vp = varfind (name);
282 return VAR_ERR_NOTDEF;
284 if (type != vp->type)
285 return VAR_ERR_BADTYPE;
287 if (!VAR_IS_SET (vp))
288 return VAR_ERR_NOTSET;
297 *(int*)val = vp->v.bool;
301 *(int*)val = vp->v.num;
309 varcmp (const void *a, const void *b)
311 return strcmp (((struct variable const *)a)->name,
312 ((struct variable const *)b)->name);
316 variable_print_all (FILE *fp)
324 qsort (vartab, sizeof (vartab) / sizeof (vartab[0]) - 1,
325 sizeof (vartab[0]), varcmp);
329 for (vp = vartab; vp->name; vp++)
331 if (!VAR_IS_SET (vp))
333 fprintf (fp, "# %s is unset", vp->name);
340 fprintf (fp, (vp->flags & VARF_OCTAL) ? "%s=%03o" : "%s=%d",
341 vp->name, vp->v.num);
345 fprintf (fp, "%s%s", vp->v.bool ? "" : "no", vp->name);
349 fprintf (fp, "%s=\"", vp->name);
350 for (s = vp->v.string; *s; s++)
356 else if ((c = escape (*s)))
357 fprintf (fp, "\\%c", c);
359 fprintf (fp, "\\%03o", *s);
369 variable_is_set (const char *name)
371 struct variable *vp = varfind (name);
375 return VAR_IS_SET (vp);
379 variable_is_true (const char *name)
383 if (variable_get (name, VART_BOOL, (void **) &n) == VAR_OK)