aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2013-05-15 16:17:51 +0000
committerSergey Poznyakoff <gray@gnu.org.ua>2013-05-15 16:17:51 +0000
commit9b83ca8638cdb8c4deafcc48d8157fe0e8da1740 (patch)
treea0dfd21b21a5cb9916afc8fb03928fa68847fe26 /src
parent8cbaa44e2f1b80dd8954a0e06e0bc8a52494237f (diff)
downloadgdbm-9b83ca8638cdb8c4deafcc48d8157fe0e8da1740.tar.gz
gdbm-9b83ca8638cdb8c4deafcc48d8157fe0e8da1740.tar.bz2
Add "pager" variable and "unset" command.
* src/gdbmtool.c (command_tab) <unset>: New command. (run_command): Get pager value from the variable. * src/gdbmtool.h (VAR_ERR_NOTSET): New error code. (variable_is_true): New function. Replaces variable_is_set, which changed semantics. * src/gram.y: Implement the unset command. * src/var.c: Support the "unset variable" notion. (VARF_INIT): New flag. (VAR_IS_SET): New define. (vartab): Mark initialized variables with VARF_INIT. New variable "pager". (open_hook): v can be NULL. (variable_set): NULL value unsets the variable. (variable_unset): New function. (variable_get): Return VAR_ERR_NOTSET if the variable is not set. (variable_is_true): Renamed from variable_is_set. (variable_is_set): New function. * src/gdbmdefs.h: Fix some typos.
Diffstat (limited to 'src')
-rw-r--r--src/gdbmdefs.h4
-rw-r--r--src/gdbmtool.c28
-rw-r--r--src/gdbmtool.h13
-rw-r--r--src/gram.y36
-rw-r--r--src/var.c136
5 files changed, 160 insertions, 57 deletions
diff --git a/src/gdbmdefs.h b/src/gdbmdefs.h
index c37e8c0..83a71c1 100644
--- a/src/gdbmdefs.h
+++ b/src/gdbmdefs.h
@@ -61,7 +61,7 @@ typedef struct {
int bucket_size; /* Size in bytes of a hash bucket struct. */
int bucket_elems; /* Number of elements in a hash bucket. */
off_t next_block; /* The next unallocated block address. */
- avail_block avail; /* This must be last because of the psuedo
+ avail_block avail; /* This must be last because of the pseudo
array in avail. This avail grows to fill
the entire block. */
} gdbm_file_header;
@@ -162,7 +162,7 @@ struct gdbm_file_info {
/* Type of file locking in use. */
enum { LOCKING_NONE = 0, LOCKING_FLOCK, LOCKING_LOCKF,
- LOCKING_FCNTL } lock_type;
+ LOCKING_FCNTL } lock_type;
/* The fatal error handling routine. */
void (*fatal_err) (const char *);
diff --git a/src/gdbmtool.c b/src/gdbmtool.c
index 6083edc..93cc175 100644
--- a/src/gdbmtool.c
+++ b/src/gdbmtool.c
@@ -54,19 +54,25 @@ opendb (char *dbname)
if (variable_get ("cachesize", VART_INT, (void**) &cache_size))
abort ();
- if (variable_get ("blocksize", VART_INT, (void**) &block_size))
- abort ();
-
- if (!variable_is_set ("lock"))
+ switch (variable_get ("blocksize", VART_INT, (void**) &block_size))
+ {
+ case VAR_OK:
+ case VAR_ERR_NOTSET:
+ break;
+ default:
+ abort ();
+ }
+
+ if (!variable_is_true ("lock"))
flags |= GDBM_NOLOCK;
- if (!variable_is_set ("mmap"))
+ if (!variable_is_true ("mmap"))
flags |= GDBM_NOMMAP;
- if (variable_is_set ("sync"))
+ if (variable_is_true ("sync"))
flags |= GDBM_SYNC;
if (open_mode == GDBM_NEWDB)
{
- if (interactive && variable_is_set ("confirm") &&
+ if (interactive && variable_is_true ("confirm") &&
access (dbname, F_OK) == 0)
{
if (!getyn (_("database %s already exists; overwrite"), dbname))
@@ -935,6 +941,9 @@ struct command command_tab[] = {
{ S(set), T_SET,
NULL, NULL, NULL,
{ { "[var=value...]" }, { NULL } }, N_("set or list variables") },
+ { S(unset), T_UNSET,
+ NULL, NULL, NULL,
+ { { "var..." }, { NULL } }, N_("unset variables") },
{ S(define), T_DEF,
NULL, NULL, NULL,
{ { "key|content", ARG_STRING },
@@ -1322,10 +1331,12 @@ run_command (struct command *cmd, struct gdbmarglist *arglist)
{
int i;
struct gdbmarg *arg;
- char *pager = getenv ("PAGER");
+ char *pager = NULL;
char argbuf[128];
size_t expected_lines, *expected_lines_ptr;
FILE *pagfp = NULL;
+
+ variable_get ("pager", VART_STRING, (void**) &pager);
arg = arglist ? arglist->head : NULL;
@@ -1487,6 +1498,7 @@ main (int argc, char *argv[])
sort_commands ();
variable_set ("open", VART_STRING, "wrcreat");
+ variable_set ("pager", VART_STRING, getenv ("PAGER"));
for (opt = parseopt_first (argc, argv, optab);
opt != EOF;
diff --git a/src/gdbmtool.h b/src/gdbmtool.h
index db18669..c850a9a 100644
--- a/src/gdbmtool.h
+++ b/src/gdbmtool.h
@@ -228,14 +228,19 @@ extern struct dsegm *dsdef[];
#define VART_BOOL 1
#define VART_INT 2
-#define VAR_OK 0
-#define VAR_ERR_NOTDEF 1
-#define VAR_ERR_BADTYPE 2
-#define VAR_ERR_BADVALUE 3
+#define VAR_OK 0 /* operation succeeded */
+#define VAR_ERR_NOTSET 1 /* Only for variable_get:
+ variable is not set */
+#define VAR_ERR_NOTDEF 2 /* no such variable */
+#define VAR_ERR_BADTYPE 3 /* variable cannot be coerced to the
+ requested type (software error) */
+#define VAR_ERR_BADVALUE 4 /* Only for variable_set: the value is
+ not valid for this variable. */
int variable_set (const char *name, int type, void *val);
int variable_get (const char *name, int type, void **val);
int variable_is_set (const char *name);
+int variable_is_true (const char *name);
void variable_print_all (FILE *fp);
diff --git a/src/gram.y b/src/gram.y
index a54ef0e..b939d8e 100644
--- a/src/gram.y
+++ b/src/gram.y
@@ -31,7 +31,9 @@ struct dsegm *dsdef[DS_MAX];
T_PAD "pad"
T_DEF "define"
T_SET "set"
+ T_UNSET "unset"
T_BOGUS
+
%token <cmd> T_CMD "command verb"
%token <num> T_NUM "number"
%token <string> T_IDENT "identifier" T_WORD "word"
@@ -244,14 +246,15 @@ set : T_SET
{
variable_print_all (stdout);
}
- | T_SET varlist
+ | T_SET asgnlist
+ | T_UNSET varlist
;
-varlist : var
- | varlist var
+asgnlist : asgn
+ | asgnlist asgn
;
-var : T_IDENT
+asgn : T_IDENT
{
int t = 1;
int rc;
@@ -304,6 +307,31 @@ var : T_IDENT
free ($3);
}
;
+
+varlist : var
+ | varlist var
+ ;
+
+var : T_IDENT
+ {
+ int rc = variable_unset ($1);
+ switch (rc)
+ {
+ case VAR_OK:
+ break;
+
+ case VAR_ERR_NOTDEF:
+ lerror (&@1, _("no such variable: %s"), $1);
+ break;
+
+ case VAR_ERR_BADVALUE:
+ lerror (&@1, _("%s: variable cannot be unset"), $1);
+ break;
+ }
+ free($1);
+ }
+ ;
+
%%
void
diff --git a/src/var.c b/src/var.c
index a518e94..a080483 100644
--- a/src/var.c
+++ b/src/var.c
@@ -19,6 +19,9 @@
#define VARF_DFL 0x00
#define VARF_SET 0x01
+#define VARF_INIT 0x02
+
+#define VAR_IS_SET(v) ((v)->flags & (VARF_SET|VARF_INIT))
union value
{
@@ -41,20 +44,21 @@ static int open_hook (struct variable *, union value *);
static struct variable vartab[] = {
/* Top-level prompt */
- { "ps1", VART_STRING, VARF_DFL, { "%p>%_" } },
+ { "ps1", VART_STRING, VARF_INIT, { "%p>%_" } },
/* Second-level prompt (used within "def" block) */
- { "ps2", VART_STRING, VARF_DFL, { "%_>%_" } },
+ { "ps2", VART_STRING, VARF_INIT, { "%_>%_" } },
/* This delimits array members */
- { "delim1", VART_STRING, VARF_DFL, { "," } },
+ { "delim1", VART_STRING, VARF_INIT, { "," } },
/* This delimits structure members */
- { "delim2", VART_STRING, VARF_DFL, { "," } },
- { "confirm", VART_BOOL, VARF_DFL, { num: 1 } },
- { "cachesize", VART_INT, VARF_DFL, { num: DEFAULT_CACHESIZE } },
+ { "delim2", VART_STRING, VARF_INIT, { "," } },
+ { "confirm", VART_BOOL, VARF_INIT, { num: 1 } },
+ { "cachesize", VART_INT, VARF_INIT, { num: DEFAULT_CACHESIZE } },
{ "blocksize", VART_INT, VARF_DFL, { num: 0 } },
{ "open", VART_STRING, VARF_DFL, { NULL }, open_hook },
- { "lock", VART_BOOL, VARF_DFL, { num: 1 } },
- { "mmap", VART_BOOL, VARF_DFL, { num: 1 } },
- { "sync", VART_BOOL, VARF_DFL, { num: 0 } },
+ { "lock", VART_BOOL, VARF_INIT, { num: 1 } },
+ { "mmap", VART_BOOL, VARF_INIT, { num: 1 } },
+ { "sync", VART_BOOL, VARF_INIT, { num: 0 } },
+ { "pager", VART_STRING, VARF_DFL },
{ NULL }
};
@@ -74,6 +78,9 @@ open_hook (struct variable *var, union value *v)
};
int i;
+ if (!v)
+ return VAR_ERR_BADVALUE;
+
for (i = 0; trans[i].s; i++)
if (strcmp (trans[i].s, v->string) == 0)
{
@@ -204,24 +211,55 @@ variable_set (const char *name, int type, void *val)
{
struct variable *vp = varfind (name);
int rc;
- union value v;
+ union value v, *valp;
if (!vp)
return VAR_ERR_NOTDEF;
- memset (&v, 0, sizeof (v));
- rc = setvar[vp->type][type] (&v, val);
- if (rc)
- return rc;
-
- if (vp->hook && (rc = vp->hook (vp, &v)) != VAR_OK)
+ if (val)
+ {
+ memset (&v, 0, sizeof (v));
+ rc = setvar[vp->type][type] (&v, val);
+ if (rc)
+ return rc;
+ valp = &v;
+ }
+ else
+ valp = NULL;
+
+ if (vp->hook && (rc = vp->hook (vp, valp)) != VAR_OK)
return rc;
if (vp->type == VART_STRING && (vp->flags && VARF_SET))
free (vp->v.string);
- vp->v = v;
- vp->flags |= VARF_SET;
+ if (!val)
+ {
+ vp->flags &= (VARF_INIT|VARF_SET);
+ }
+ else
+ {
+ vp->v = v;
+ vp->flags &= ~VARF_INIT;
+ vp->flags |= VARF_SET;
+ }
+
+ return VAR_OK;
+}
+
+int
+variable_unset (const char *name)
+{
+ struct variable *vp = varfind (name);
+ int rc;
+
+ if (!vp)
+ return VAR_ERR_NOTDEF;
+
+ if (vp->hook && (rc = vp->hook (vp, NULL)) != VAR_OK)
+ return rc;
+
+ vp->flags &= ~(VARF_INIT|VARF_SET);
return VAR_OK;
}
@@ -236,6 +274,9 @@ variable_get (const char *name, int type, void **val)
if (type != vp->type)
return VAR_ERR_BADTYPE;
+
+ if (!VAR_IS_SET (vp))
+ return VAR_ERR_NOTSET;
switch (vp->type)
{
@@ -263,38 +304,55 @@ variable_print_all (FILE *fp)
for (vp = vartab; vp->name; vp++)
{
- switch (vp->type)
+ if (!VAR_IS_SET (vp))
+ {
+ fprintf (fp, "# %s is unset", vp->name);
+ }
+ else
{
- case VART_INT:
- fprintf (fp, "%s=%d", vp->name, vp->v.num);
- break;
-
- case VART_BOOL:
- fprintf (fp, "%s%s", vp->v.bool ? "" : "no", vp->name);
- break;
-
- case VART_STRING:
- fprintf (fp, "%s=\"", vp->name);
- for (s = vp->v.string; *s; s++)
+ switch (vp->type)
{
- int c;
+ case VART_INT:
+ fprintf (fp, "%s=%d", vp->name, vp->v.num);
+ break;
- if (isprint (*s))
- fputc (*s, fp);
- else if ((c = escape (*s)))
- fprintf (fp, "\\%c", c);
- else
- fprintf (fp, "\\%03o", *s);
+ case VART_BOOL:
+ fprintf (fp, "%s%s", vp->v.bool ? "" : "no", vp->name);
+ break;
+
+ case VART_STRING:
+ fprintf (fp, "%s=\"", vp->name);
+ for (s = vp->v.string; *s; s++)
+ {
+ int c;
+
+ if (isprint (*s))
+ fputc (*s, fp);
+ else if ((c = escape (*s)))
+ fprintf (fp, "\\%c", c);
+ else
+ fprintf (fp, "\\%03o", *s);
+ }
+ fprintf (fp, "\"");
}
- fprintf (fp, "\"");
}
fputc ('\n', fp);
}
}
-
+
int
variable_is_set (const char *name)
{
+ struct variable *vp = varfind (name);
+
+ if (!vp)
+ return 0;
+ return VAR_IS_SET (vp);
+}
+
+int
+variable_is_true (const char *name)
+{
int n;
if (variable_get (name, VART_BOOL, (void **) &n))

Return to:

Send suggestions and report system problems to the System administrator.