diff options
author | Sergey Poznyakoff <gray@gnu.org> | 2021-08-12 08:19:07 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org> | 2021-08-12 08:19:36 +0300 |
commit | cc7051ae2ea384863937083a3a60a5a008d511a5 (patch) | |
tree | 59cc1fdd4bb35ca0afafaaa56372ef631c3d1b59 /src | |
parent | d19407eaa4b00a724c4ff3744c2f49269183da26 (diff) | |
download | gdbm-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.c | 105 | ||||
-rw-r--r-- | src/gdbmtool.c | 9 | ||||
-rw-r--r-- | src/gdbmtool.h | 5 | ||||
-rw-r--r-- | src/lex.l | 4 | ||||
-rw-r--r-- | src/var.c | 287 |
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" @@ -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 * @@ -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; +} + + |