aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2013-05-16 15:32:45 +0000
committerSergey Poznyakoff <gray@gnu.org.ua>2013-05-16 15:32:45 +0000
commit979486e1b46a894fc9de2abe6eb8985536a5013c (patch)
treee9e61bcfd9d1945c612a54e080d4fdc2e87cbad5 /src
parente5fccca3abee9093f4d1e50823addca8e6c778a6 (diff)
downloadgdbm-979486e1b46a894fc9de2abe6eb8985536a5013c.tar.gz
gdbm-979486e1b46a894fc9de2abe6eb8985536a5013c.tar.bz2
Improve handling of the variables.
* src/gdbmtool.c (opendb): Allow for unset variables. * src/gram.y: Improve error detection. * src/lex.l: Handle multiline strings. (pe_file_name): file_name can be NULL. * src/var.c (VARF_PROT): New flag. Protects the variable from being unset. (vartab): Use VARF_PROT if needed. (s2b): Fix return values. (variable_set, variable_unset): Return error if attempting to unset a variable marked with VARF_PROT. * doc/gdbm.info: Update. * doc/gdbmtool.1: Update.
Diffstat (limited to 'src')
-rw-r--r--src/gdbmtool.c21
-rw-r--r--src/gram.y8
-rw-r--r--src/lex.l44
-rw-r--r--src/var.c25
4 files changed, 65 insertions, 33 deletions
diff --git a/src/gdbmtool.c b/src/gdbmtool.c
index 72f4cb2..0c75742 100644
--- a/src/gdbmtool.c
+++ b/src/gdbmtool.c
@@ -46,13 +46,19 @@ unsigned input_line;
static int
opendb (char *dbname)
{
- int cache_size;
- int block_size;
+ int cache_size = 0;
+ int block_size = 0;
int flags = 0;
GDBM_FILE db;
- if (variable_get ("cachesize", VART_INT, (void**) &cache_size))
- abort ();
+ switch (variable_get ("cachesize", VART_INT, (void**) &cache_size))
+ {
+ case VAR_OK:
+ case VAR_ERR_NOTSET:
+ break;
+ default:
+ abort ();
+ }
switch (variable_get ("blocksize", VART_INT, (void**) &block_size))
{
case VAR_OK:
@@ -88,10 +94,9 @@ opendb (char *dbname)
return 1;
}
- if (gdbm_setopt (db, GDBM_CACHESIZE, &cache_size, sizeof (int)) ==
- -1)
- terror (_("gdbm_setopt failed: %s"),
- gdbm_strerror (gdbm_errno));
+ if (cache_size &&
+ gdbm_setopt (db, GDBM_CACHESIZE, &cache_size, sizeof (int)) == -1)
+ terror (_("gdbm_setopt failed: %s"), gdbm_strerror (gdbm_errno));
if (gdbm_file)
gdbm_close (gdbm_file);
diff --git a/src/gram.y b/src/gram.y
index b939d8e..fde98a2 100644
--- a/src/gram.y
+++ b/src/gram.y
@@ -280,6 +280,9 @@ asgn : T_IDENT
case VAR_ERR_BADTYPE:
lerror (&@1, _("%s is not a boolean variable"), varname);
break;
+
+ default:
+ lerror (&@1, _("unexpected error setting %s: %d"), $1, rc);
}
free($1);
}
@@ -302,8 +305,11 @@ asgn : T_IDENT
case VAR_ERR_BADVALUE:
lerror (&@1, _("%s: value %s is not allowed"), $1, $3);
break;
+
+ default:
+ lerror (&@1, _("unexpected error setting %s: %d"), $1, rc);
}
- free($1);
+ free ($1);
free ($3);
}
;
diff --git a/src/lex.l b/src/lex.l
index d8d9eb0..abb9047 100644
--- a/src/lex.l
+++ b/src/lex.l
@@ -196,7 +196,7 @@ setsource (const char *name, int intr)
%option nounput
-%x STR DEF
+%x STR MLSTR DEF
WS [ \t][ \t]*
IDENT [a-zA-Z_][a-zA-Z_0-9-]*
@@ -259,7 +259,7 @@ O [0-7]
return command_lookup (p, &yylloc, &yylval.cmd);
}
<DEF>{IDENT} { if ((yylval.type = datadef_lookup (yytext)))
- return T_TYPE;
+ return T_TYPE;
else
{
yylval.string = estrdup (yytext);
@@ -269,23 +269,27 @@ O [0-7]
{IDENT} { yylval.string = estrdup (yytext);
return T_IDENT;
}
-<INITIAL,DEF>[^ \t\n\[\]{},=]+ { yylval.string = estrdup (yytext);
- return T_WORD; }
+<INITIAL,DEF>[^ \"\t\n\[\]{},=]+ { yylval.string = estrdup (yytext);
+ return T_WORD; }
\"[^\\\"\n]*\" { yylval.string = emalloc (yyleng - 1);
memcpy (yylval.string, yytext+1, yyleng-2);
yylval.string[yyleng-2] = 0;
return T_WORD; }
+\"[^\\\"\n]*\\$ { string_begin ();
+ string_add (yytext + 1, yyleng - 2);
+ BEGIN (MLSTR); }
\"[^\\\"\n]*\\. { string_begin ();
string_add (yytext + 1, yyleng - 3);
string_addc (unescape (yytext[yyleng-1]));
BEGIN (STR); }
-<STR>[^\\\"\n]*\" { if (yyleng > 1)
- string_add (yytext, yyleng - 1);
- yylval.string = string_end ();
- BEGIN (INITIAL);
- return T_WORD; }
-<STR>[^\\\"\n]*\\. { string_add (yytext, yyleng - 2);
- string_addc (unescape (yytext[yyleng-1])); }
+<STR,MLSTR>[^\\\"\n]*\" { if (yyleng > 1)
+ string_add (yytext, yyleng - 1);
+ yylval.string = string_end ();
+ BEGIN (INITIAL);
+ return T_WORD; }
+<STR,MLSTR>[^\\\"\n]*\\$ { string_add (yytext, yyleng - 1); }
+<STR,MLSTR>[^\\\"\n]*\\. { string_add (yytext, yyleng - 2);
+ string_addc (unescape (yytext[yyleng-1])); }
<INITIAL,DEF>{WS} ;
<DEF>\n { advance_line (); }
\n { advance_line (); return '\n'; }
@@ -453,7 +457,8 @@ struct prompt_exp;
void
pe_file_name (struct prompt_exp *p)
{
- fwrite (file_name, strlen (file_name), 1, stdout);
+ if (file_name)
+ fwrite (file_name, strlen (file_name), 1, stdout);
}
void
@@ -520,7 +525,7 @@ expand_char (int c)
char const *
psname ()
{
- if (YYSTATE == DEF)
+ if (YYSTATE == DEF || YYSTATE == MLSTR)
return "ps2";
return "ps1";
}
@@ -531,9 +536,18 @@ print_prompt ()
const char *s;
const char *prompt;
- if (variable_get (psname (), VART_STRING, (void *) &prompt))
- abort ();
+ switch (variable_get (psname (), VART_STRING, (void *) &prompt))
+ {
+ case VAR_OK:
+ break;
+ case VAR_ERR_NOTSET:
+ return;
+
+ default:
+ abort ();
+ }
+
for (s = prompt; *s; s++)
{
if (*s == '%')
diff --git a/src/var.c b/src/var.c
index 20db896..54122eb 100644
--- a/src/var.c
+++ b/src/var.c
@@ -20,6 +20,7 @@
#define VARF_DFL 0x00
#define VARF_SET 0x01
#define VARF_INIT 0x02
+#define VARF_PROT 0x04
#define VAR_IS_SET(v) ((v)->flags & (VARF_SET|VARF_INIT))
@@ -48,12 +49,12 @@ static struct variable vartab[] = {
/* Second-level prompt (used within "def" block) */
{ "ps2", VART_STRING, VARF_INIT, { "%_>%_" } },
/* This delimits array members */
- { "delim1", VART_STRING, VARF_INIT, { "," } },
+ { "delim1", VART_STRING, VARF_INIT|VARF_PROT, { "," } },
/* This delimits structure members */
- { "delim2", VART_STRING, VARF_INIT, { "," } },
+ { "delim2", VART_STRING, VARF_INIT|VARF_PROT, { "," } },
{ "confirm", VART_BOOL, VARF_INIT, { num: 1 } },
- { "cachesize", VART_INT, VARF_INIT, { num: DEFAULT_CACHESIZE } },
- { "blocksize", VART_INT, VARF_DFL, { num: 0 } },
+ { "cachesize", VART_INT, VARF_DFL },
+ { "blocksize", VART_INT, VARF_DFL },
{ "open", VART_STRING, VARF_DFL, { NULL }, open_hook },
{ "lock", VART_BOOL, VARF_INIT, { num: 1 } },
{ "mmap", VART_BOOL, VARF_INIT, { num: 1 } },
@@ -142,14 +143,14 @@ s2b (union value *vp, void *val)
if (strcasecmp (trueval[i], val) == 0)
{
vp->bool = 1;
- return 0;
+ return VAR_OK;
}
for (i = 0; falseval[i]; i++)
if (strcasecmp (falseval[i], val) == 0)
{
vp->bool = 0;
- return 1;
+ return VAR_OK;
}
n = strtoul (val, &p, 0);
@@ -226,12 +227,16 @@ variable_set (const char *name, int type, void *val)
valp = &v;
}
else
- valp = NULL;
+ {
+ if (vp->flags & VARF_PROT)
+ return VAR_ERR_BADVALUE;
+ valp = NULL;
+ }
if (vp->hook && (rc = vp->hook (vp, valp)) != VAR_OK)
return rc;
-
- if (vp->type == VART_STRING && (vp->flags && VARF_SET))
+
+ if (vp->type == VART_STRING && (vp->flags & VARF_SET))
free (vp->v.string);
if (!val)
@@ -256,6 +261,8 @@ variable_unset (const char *name)
if (!vp)
return VAR_ERR_NOTDEF;
+ if (vp->flags & VARF_PROT)
+ return VAR_ERR_BADVALUE;
if (vp->hook && (rc = vp->hook (vp, NULL)) != VAR_OK)
return rc;

Return to:

Send suggestions and report system problems to the System administrator.