summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org>2021-08-12 08:19:07 +0300
committerSergey Poznyakoff <gray@gnu.org>2021-08-12 08:19:36 +0300
commitcc7051ae2ea384863937083a3a60a5a008d511a5 (patch)
tree59cc1fdd4bb35ca0afafaaa56372ef631c3d1b59 /src
parentd19407eaa4b00a724c4ff3744c2f49269183da26 (diff)
downloadgdbm-cc7051ae2ea384863937083a3a60a5a008d511a5.tar.gz
gdbmshell: get rid of remaining globals
Use gdbmshell variables instead * src/gdbmshell.c (file_name, file_descr) (open_mode, open_format): Remove globals. (opendb,checkdb) (open_handler,import_handler) (status_handler): Use variables instead of globals. (command_tab): Mark the "open" parameter as optional. * src/gdbmtool.c (gdbmtool_init): Use variables instead of globals. * src/gdbmtool.h (file_name, file_descr) (open_mode, open_format): Remove globals. * src/lex.l: Use variables instead of globals. * src/var.c (variable): Rename hook to sethook. New field: typeconv. (vartab): New variables: "filename", "fd". (variable_get): Use typeconv if provided. * tests/gdbmtool/base.exp: Fix expected output. * tests/gdbmtool00.at: Likewise. * tests/gdbmtool01.at: Likewise.
Diffstat (limited to 'src')
-rw-r--r--src/gdbmshell.c105
-rw-r--r--src/gdbmtool.c9
-rw-r--r--src/gdbmtool.h5
-rw-r--r--src/lex.l4
-rw-r--r--src/var.c287
5 files changed, 296 insertions, 114 deletions
diff --git a/src/gdbmshell.c b/src/gdbmshell.c
index 998e40e..e117cc2 100644
--- a/src/gdbmshell.c
+++ b/src/gdbmshell.c
@@ -30,11 +30,6 @@
# include <locale.h>
#endif
-char *file_name = NULL; /* Database file name */
-int file_descr = -1; /* Database file descriptor */
-int open_mode; /* Default open mode */
-int open_format; /* Default format for the open command */
-
static GDBM_FILE gdbm_file = NULL; /* Database to operate upon */
static datum key_data; /* Current key */
static datum return_data; /* Current data */
@@ -53,9 +48,6 @@ closedb (void)
{
gdbm_close (gdbm_file);
gdbm_file = NULL;
- free (file_name);
- file_name = NULL;
- file_descr = -1;
}
datum_free (&key_data);
@@ -67,9 +59,10 @@ opendb (char *dbname, int fd)
{
int cache_size = 0;
int block_size = 0;
- int flags = open_format;
+ int flags;
int filemode;
GDBM_FILE db;
+ int n;
switch (variable_get ("cachesize", VART_INT, (void**) &cache_size))
{
@@ -88,14 +81,10 @@ opendb (char *dbname, int fd)
abort ();
}
- if (!variable_is_true ("lock"))
- flags |= GDBM_NOLOCK;
- if (!variable_is_true ("mmap"))
- flags |= GDBM_NOMMAP;
- if (variable_is_true ("sync"))
- flags |= GDBM_SYNC;
+ if (variable_get ("open", VART_INT, (void**) &flags) != VAR_OK)
+ abort ();
- if (open_mode == GDBM_NEWDB)
+ if (flags == GDBM_NEWDB)
{
if (interactive () && variable_is_true ("confirm") &&
access (dbname, F_OK) == 0)
@@ -104,14 +93,30 @@ opendb (char *dbname, int fd)
return 1;
}
}
+
+ if (variable_get ("format", VART_INT, (void**) &n) != VAR_OK)
+ abort ();
+
+ flags |= n;
+
+ if (!variable_is_true ("lock"))
+ flags |= GDBM_NOLOCK;
+ if (!variable_is_true ("mmap"))
+ flags |= GDBM_NOMMAP;
+ if (variable_is_true ("sync"))
+ flags |= GDBM_SYNC;
if (variable_get ("filemode", VART_INT, (void**) &filemode))
abort ();
if (fd > 0)
- db = gdbm_fd_open (fd, dbname, block_size, open_mode | flags | GDBM_CLOERROR, NULL);
+ db = gdbm_fd_open (fd, dbname, block_size, flags | GDBM_CLOERROR, NULL);
else
- db = gdbm_open (dbname, block_size, open_mode | flags, filemode, NULL);
+ {
+ char *name = tildexpand (dbname);
+ db = gdbm_open (name, block_size, flags, filemode, NULL);
+ free (name);
+ }
if (db == NULL)
{
@@ -149,12 +154,11 @@ checkdb (void)
{
if (!gdbm_file)
{
- if (!file_name)
- {
- file_name = estrdup (GDBMTOOL_DEFFILE);
- terror (_("warning: using default database file %s"), file_name);
- }
- return opendb (file_name, file_descr);
+ char *filename;
+ int fd = -1;
+ variable_get ("filename", VART_STRING, (void**) &filename);
+ variable_get ("fd", VART_INT, (void**) &fd);
+ return opendb (filename, fd);
}
return 0;
}
@@ -357,12 +361,27 @@ static void
open_handler (struct command_param *param,
struct command_environ *cenv GDBM_ARG_UNUSED)
{
- char *name = tildexpand (PARAM_STRING (param, 0));
+ char *filename;
+ int fd = -1;
+
closedb ();
- if (opendb (name, -1) == 0)
- file_name = name;
+
+ if (param->argc == 1)
+ filename = PARAM_STRING (param, 0);
else
- free (name);
+ {
+ variable_get ("filename", VART_STRING, (void**) &filename);
+ variable_get ("fd", VART_INT, (void**) &fd);
+ }
+
+ if (opendb (filename, fd) == 0)
+ {
+ variable_set ("filename", VART_STRING, filename);
+ if (fd >= 0)
+ variable_set ("fd", VART_INT, &fd);
+ else
+ variable_unset ("fd");
+ }
}
/* Close database */
@@ -1270,7 +1289,8 @@ import_handler (struct command_param *param,
int meta_mask = 0;
int i;
int rc;
-
+ char *file_name;
+
for (i = 0; i < param->argc; i++)
{
if (strcmp (PARAM_STRING (param, i), "replace") == 0)
@@ -1289,12 +1309,16 @@ import_handler (struct command_param *param,
meta_mask, &err_line);
if (rc && gdbm_errno == GDBM_NO_DBNAME)
{
- int t = open_mode;
+ char *save_mode;
- open_mode = GDBM_NEWDB;
- rc = checkdb ();
- open_mode = t;
+ variable_get ("open", VART_STRING, (void**) &save_mode);
+ save_mode = estrdup (save_mode);
+ variable_set ("open", VART_STRING, "newdb");
+ rc = checkdb ();
+ variable_set ("open", VART_STRING, save_mode);
+ free (save_mode);
+
if (rc)
return;
@@ -1325,6 +1349,11 @@ import_handler (struct command_param *param,
free (file_name);
if (gdbm_setopt (gdbm_file, GDBM_GETDBNAME, &file_name, sizeof (file_name)))
terror (_("gdbm_setopt failed: %s"), gdbm_strerror (gdbm_errno));
+ else
+ {
+ variable_set ("filename", VART_STRING, file_name);
+ variable_unset ("fd");
+ }
}
/* status - print current program status */
@@ -1332,10 +1361,10 @@ static void
status_handler (struct command_param *param GDBM_ARG_UNUSED,
struct command_environ *cenv)
{
- if (file_name)
- fprintf (cenv->fp, _("Database file: %s\n"), file_name);
- else
- fprintf (cenv->fp, "%s\n", _("No database name"));
+ char *file_name;
+
+ variable_get ("filename", VART_STRING, (void**) &file_name);
+ fprintf (cenv->fp, _("Database file: %s\n"), file_name);
if (gdbm_file)
fprintf (cenv->fp, "%s\n", _("Database is open"));
else
@@ -1723,7 +1752,7 @@ static struct command command_tab[] = {
N_("close the database") },
{ S(open), T_CMD,
NULL, open_handler, NULL,
- { { "FILE", GDBM_ARG_STRING }, { NULL } },
+ { { "[FILE]", GDBM_ARG_STRING }, { NULL } },
FALSE,
REPEAT_NEVER,
N_("open new database") },
diff --git a/src/gdbmtool.c b/src/gdbmtool.c
index 8dacce5..888be8e 100644
--- a/src/gdbmtool.c
+++ b/src/gdbmtool.c
@@ -136,8 +136,7 @@ gdbmtool_init (void *data, instream_t *pinstr)
switch (opt)
{
case 'd':
- file_descr = atoi (optarg);
- if (file_descr <= 0)
+ if (variable_set ("fd", VART_STRING, optarg) != VAR_OK)
{
terror (_("invalid file descriptor: %s"), optarg);
exit (EXIT_USAGE);
@@ -182,9 +181,9 @@ gdbmtool_init (void *data, instream_t *pinstr)
case 'b':
variable_set ("blocksize", VART_STRING, optarg);
break;
-
+
case 'g':
- file_name = estrdup (optarg);
+ variable_set ("filename", VART_STRING, optarg);
break;
case 'q':
@@ -222,7 +221,7 @@ gdbmtool_init (void *data, instream_t *pinstr)
if (argc >= 1)
{
- file_name = estrdup (argv[0]);
+ variable_set ("filename", VART_STRING, argv[0]);
argc--;
argv++;
if (argc)
diff --git a/src/gdbmtool.h b/src/gdbmtool.h
index 15611dd..1f20b5a 100644
--- a/src/gdbmtool.h
+++ b/src/gdbmtool.h
@@ -107,11 +107,6 @@ void terror (const char *fmt, ...)
char *make_prompt (void);
-extern char *file_name;
-extern int file_descr;
-extern int open_mode;
-extern int open_format;
-
#define GDBMTOOLRC ".gdbmtoolrc"
#define GDBMTOOL_DEFFILE "junk.gdbm"
diff --git a/src/lex.l b/src/lex.l
index 1a57a3a..f35d2fc 100644
--- a/src/lex.l
+++ b/src/lex.l
@@ -503,7 +503,9 @@ lerror (struct locus *loc, const char *fmt, ...)
static struct slist *
pe_file_name (void)
{
- return file_name ? slist_new (file_name) : NULL;
+ char *name = NULL;
+ variable_get ("filename", VART_STRING, (void**) &name);
+ return name ? slist_new (name) : NULL;
}
static struct slist *
diff --git a/src/var.c b/src/var.c
index faed341..6038d13 100644
--- a/src/var.c
+++ b/src/var.c
@@ -38,76 +38,137 @@ struct variable
int flags;
union value init;
union value v;
- int (*hook) (struct variable *, union value *);
+ int (*sethook) (struct variable *, union value *);
+ int (*typeconv) (struct variable *, int, void **);
};
-static int open_hook (struct variable *, union value *);
-static int format_hook (struct variable *, union value *);
+static int open_sethook (struct variable *, union value *);
+static int open_typeconv (struct variable *var, int type, void **retptr);
+static int format_sethook (struct variable *, union value *);
+static int format_typeconv (struct variable *var, int type, void **retptr);
+static int fd_sethook (struct variable *, union value *);
static struct variable vartab[] = {
/* Top-level prompt */
- { "ps1", VART_STRING, VARF_INIT, { .string = "%p>%_" } },
+ {
+ .name = "ps1",
+ .type = VART_STRING,
+ .flags = VARF_INIT,
+ .init = { .string = "%p>%_" }
+ },
/* Second-level prompt (used within "def" block) */
- { "ps2", VART_STRING, VARF_INIT, { .string = "%_>%_" } },
+ {
+ .name = "ps2",
+ .type = VART_STRING,
+ .flags = VARF_INIT,
+ .init = { .string = "%_>%_" }
+ },
/* This delimits array members */
- { "delim1", VART_STRING, VARF_INIT|VARF_PROT, { .string = "," } },
+ {
+ .name = "delim1",
+ .type = VART_STRING,
+ .flags = VARF_INIT|VARF_PROT,
+ .init = { .string = "," }
+ },
/* This delimits structure members */
- { "delim2", VART_STRING, VARF_INIT|VARF_PROT, { .string = "," } },
- { "confirm", VART_BOOL, VARF_INIT, { .bool = 1 } },
- { "cachesize", VART_INT, VARF_DFL },
- { "blocksize", VART_INT, VARF_DFL },
- { "open", VART_STRING, VARF_DFL, { NULL }, { NULL }, open_hook },
- { "lock", VART_BOOL, VARF_INIT, { .bool = 1 } },
- { "mmap", VART_BOOL, VARF_INIT, { .bool = 1 } },
- { "sync", VART_BOOL, VARF_INIT, { .bool = 0 } },
- { "coalesce", VART_BOOL, VARF_INIT, { .bool = 0 } },
- { "centfree", VART_BOOL, VARF_INIT, { .bool = 0 } },
- { "filemode", VART_INT, VARF_INIT|VARF_OCTAL|VARF_PROT, { .num = 0644 } },
- { "format", VART_STRING, VARF_INIT, { .string = "standard" }, { NULL }, format_hook },
- { "pager", VART_STRING, VARF_DFL },
- { "quiet", VART_BOOL, VARF_DFL },
+ {
+ .name = "delim2",
+ .type = VART_STRING,
+ .flags = VARF_INIT|VARF_PROT,
+ .init = { .string = "," }
+ },
+ {
+ .name = "confirm",
+ .type = VART_BOOL,
+ .flags = VARF_INIT,
+ .init = { .bool = 1 }
+ },
+ {
+ .name = "cachesize",
+ .type = VART_INT,
+ .flags = VARF_DFL
+ },
+ {
+ .name = "blocksize",
+ .type = VART_INT,
+ .flags = VARF_DFL
+ },
+ {
+ .name = "open",
+ .type = VART_STRING,
+ .flags = VARF_DFL,
+ .sethook = open_sethook,
+ .typeconv = open_typeconv
+ },
+ {
+ .name = "lock",
+ .type = VART_BOOL,
+ .flags = VARF_INIT,
+ .init = { .bool = 1 }
+ },
+ {
+ .name = "mmap",
+ .type = VART_BOOL,
+ .flags = VARF_INIT,
+ .init = { .bool = 1 }
+ },
+ {
+ .name = "sync",
+ .type = VART_BOOL,
+ .flags = VARF_INIT,
+ .init = { .bool = 0 }
+ },
+ {
+ .name = "coalesce",
+ .type = VART_BOOL,
+ .flags = VARF_INIT,
+ .init = { .bool = 0 }
+ },
+ {
+ .name = "centfree",
+ .type = VART_BOOL,
+ .flags = VARF_INIT,
+ .init = { .bool = 0 }
+ },
+ {
+ .name = "filemode",
+ .type = VART_INT,
+ .flags = VARF_INIT|VARF_OCTAL|VARF_PROT,
+ .init = { .num = 0644 }
+ },
+ {
+ .name = "format",
+ .type = VART_STRING,
+ .flags = VARF_INIT,
+ .init = { .string = "standard" },
+ .sethook = format_sethook,
+ .typeconv = format_typeconv
+ },
+ {
+ .name = "pager",
+ .type = VART_STRING,
+ .flags = VARF_DFL
+ },
+ {
+ .name = "quiet",
+ .type = VART_BOOL,
+ .flags = VARF_DFL
+ },
+ {
+ .name = "filename",
+ .type = VART_STRING,
+ .flags = VARF_INIT|VARF_PROT,
+ { .string = GDBMTOOL_DEFFILE }
+ },
+ {
+ .name = "fd",
+ .type = VART_INT,
+ .flags = VARF_DFL,
+ .sethook = fd_sethook
+ },
{ NULL }
};
-static int
-open_hook (struct variable *var, union value *v)
-{
- static struct {
- char *s;
- int t;
- } trans[] = {
- { "newdb", GDBM_NEWDB },
- { "wrcreat", GDBM_WRCREAT },
- { "rw", GDBM_WRCREAT },
- { "reader", GDBM_READER },
- { "readonly", GDBM_READER },
- { NULL }
- };
- int i;
-
- if (!v)
- return VAR_ERR_BADVALUE;
-
- for (i = 0; trans[i].s; i++)
- if (strcmp (trans[i].s, v->string) == 0)
- {
- open_mode = trans[i].t;
- return VAR_OK;
- }
-
- return VAR_ERR_BADVALUE;
-}
-
-static int
-format_hook (struct variable *var, union value *v)
-{
- int n = _gdbm_str2fmt (v->string);
- if (n == -1)
- return VAR_ERR_BADVALUE;
- open_format = n;
- return VAR_OK;
-}
-
static struct variable *
varfind (const char *name)
{
@@ -248,7 +309,7 @@ variable_set (const char *name, int type, void *val)
valp = NULL;
}
- if (vp->hook && (rc = vp->hook (vp, valp)) != VAR_OK)
+ if (vp->sethook && (rc = vp->sethook (vp, valp)) != VAR_OK)
return rc;
if (vp->type == VART_STRING && (vp->flags & VARF_SET))
@@ -278,7 +339,7 @@ variable_unset (const char *name)
if (vp->flags & VARF_PROT)
return VAR_ERR_BADVALUE;
- if (vp->hook && (rc = vp->hook (vp, NULL)) != VAR_OK)
+ if (vp->sethook && (rc = vp->sethook (vp, NULL)) != VAR_OK)
return rc;
vp->flags &= ~VARF_SET;
@@ -294,12 +355,19 @@ variable_get (const char *name, int type, void **val)
if (!vp)
return VAR_ERR_NOTDEF;
- if (type != vp->type)
- return VAR_ERR_BADTYPE;
-
if (!VAR_IS_SET (vp))
return VAR_ERR_NOTSET;
-
+
+ if (type != vp->type)
+ {
+ if (vp->typeconv)
+ {
+ return vp->typeconv (vp, type, val);
+ }
+ else
+ return VAR_ERR_BADTYPE;
+ }
+
switch (vp->type)
{
case VART_STRING:
@@ -427,5 +495,94 @@ variables_init (void)
}
}
}
+
+struct kwtrans
+{
+ char *s;
+ int t;
+};
+
+static int
+string_to_int (char const *s, struct kwtrans *t)
+{
+ int i;
+
+ for (i = 0; t[i].s; i++)
+ if (strcmp (t[i].s, s) == 0)
+ return t[i].t;
+ return -1;
+}
+
+#if 0
+static char const *
+int_to_string (int n, struct kwtrans *t)
+{
+ int i;
+
+ for (i = 0; t[i].s; i++)
+ if (t[i].t == n)
+ return t[i].s;
+ return NULL;
+}
+#endif
+
+static struct kwtrans db_open_flags[] = {
+ { "newdb", GDBM_NEWDB },
+ { "wrcreat", GDBM_WRCREAT },
+ { "rw", GDBM_WRCREAT },
+ { "reader", GDBM_READER },
+ { "readonly", GDBM_READER },
+ { NULL }
+};
+
+static int
+open_sethook (struct variable *var, union value *v)
+{
+ int n;
+ if (!v)
+ return VAR_ERR_BADVALUE;
+ n = string_to_int (v->string, db_open_flags);
+ if (n == -1)
+ return VAR_ERR_BADVALUE;
+ return VAR_OK;
+}
+
+static int
+open_typeconv (struct variable *var, int type, void **retptr)
+{
+ if (type == VART_INT)
+ {
+ *(int*) retptr = string_to_int (var->v.string, db_open_flags);
+ return VAR_OK;
+ }
+ return VAR_ERR_BADTYPE;
+}
+
+static int
+format_sethook (struct variable *var, union value *v)
+{
+ return _gdbm_str2fmt (v->string) == -1 ? VAR_ERR_BADVALUE : VAR_OK;
+}
+
+static int
+format_typeconv (struct variable *var, int type, void **retptr)
+{
+ if (type == VART_INT)
+ {
+ *(int*) retptr = _gdbm_str2fmt (var->v.string);
+ return VAR_OK;
+ }
+ return VAR_ERR_BADTYPE;
+}
+
+static int
+fd_sethook (struct variable *var, union value *v)
+{
+ if (v->num < 0)
+ return VAR_ERR_BADVALUE;
+ return VAR_OK;
+}
+
+