From 9b83ca8638cdb8c4deafcc48d8157fe0e8da1740 Mon Sep 17 00:00:00 2001 From: Sergey Poznyakoff Date: Wed, 15 May 2013 16:17:51 +0000 Subject: Add "pager" variable and "unset" command. * src/gdbmtool.c (command_tab) : 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. --- src/gdbmdefs.h | 4 +- src/gdbmtool.c | 28 ++++++++---- src/gdbmtool.h | 13 ++++-- src/gram.y | 36 +++++++++++++-- src/var.c | 136 ++++++++++++++++++++++++++++++++++++++++----------------- 5 files changed, 160 insertions(+), 57 deletions(-) (limited to 'src') 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 T_CMD "command verb" %token T_NUM "number" %token 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,37 +304,54 @@ 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; -- cgit v1.2.1