diff options
author | Sergey Poznyakoff <gray@gnu.org> | 2018-05-23 19:18:14 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org> | 2018-05-23 19:18:14 +0300 |
commit | 7edbff3372dfd387e4f6da45f43ba8ada6dfbe43 (patch) | |
tree | d3049ab8c07773c82104e720f92be555ae276179 /src/input-file.c | |
parent | 008b71a4d58ad33cf5a41e2aa55b9393e8420531 (diff) | |
download | gdbm-7edbff3372dfd387e4f6da45f43ba8ada6dfbe43.tar.gz gdbm-7edbff3372dfd387e4f6da45f43ba8ada6dfbe43.tar.bz2 |
gdbmtool: accept commands from command line as well as from file
Commands can be supplied to gdbmtool in three ways:
1. From a file, using the --file (-f) option:
gdbmtool -f comfile
2. From the command line, if first argument is the database name:
gdbmtool test.db count \; fetch mykey \; avail
Note the use of semicolon to delimit commands.
3. From the interactive shell, if neither of the above is used.
* src/Makefile.am: Add new sources.
* src/gdbmtool.c: Use new stream functions for input.
* src/gdbmtool.h (setsource): Remove proto.
(instream_t): New data type.
(instream_name, instream_read)
(instream_close, instream_interactive)
(instream_eq): New functions.
(instream_stdin_create)
(instream_argv_create)
(instream_file_create)
(interactive, input_context_push): New protos.
* src/gram.y: Accept ; in place of newline.
* src/input-argv.c: New file.
* src/input-file.c: New file.
* src/input-rl.c: Rewrite to provide instream_t API.
* src/input-std.c: Likewise.
* src/lex.l: Rewrite.
* tests/.gitignore: Update.
* tests/Makefile.am: Add new tests. Incorporate
DejaGNU tests.
* tests/config/default.exp: New file.
* tests/gdbmtool/base.exp: New file.
* tests/gdbmtool00.at: New file.
* tests/gdbmtool01.at: New file.
* tests/gdbmtool02.at: New file.
* tests/testsuite.at: Include new tests.
Diffstat (limited to 'src/input-file.c')
-rw-r--r-- | src/input-file.c | 88 |
1 files changed, 88 insertions, 0 deletions
diff --git a/src/input-file.c b/src/input-file.c new file mode 100644 index 0000000..5cbb030 --- /dev/null +++ b/src/input-file.c @@ -0,0 +1,88 @@ +/* This file is part of GDBM, the GNU data base manager. + Copyright (C) 2018 Free Software Foundation, Inc. + + GDBM is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + GDBM is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GDBM. If not, see <http://www.gnu.org/licenses/>. */ + +#include "gdbmtool.h" + +struct instream_file +{ + struct instream base; /* Base structure */ + FILE *fp; /* Opened file */ + dev_t dev; /* Device number */ + ino_t ino; /* Inode number */ +}; + +static ssize_t +instream_file_read (instream_t istr, char *buf, size_t size) +{ + struct instream_file *file = (struct instream_file *)istr; + return fread (buf, 1, size, file->fp); +} + +static void +instream_file_close (instream_t istr) +{ + struct instream_file *file = (struct instream_file *)istr; + fclose (file->fp); + free (file->base.in_name); + free (file); +} + +static int +instream_file_eq (instream_t a, instream_t b) +{ + struct instream_file *file_a = (struct instream_file *)a; + struct instream_file *file_b = (struct instream_file *)b; + return file_a->dev == file_b->dev && file_a->ino == file_b->ino; +} + +instream_t +instream_file_create (char const *name) +{ + struct instream_file *istr; + struct stat st; + FILE *fp; + + if (stat (name, &st)) + { + terror (_("cannot open `%s': %s"), name, strerror (errno)); + return NULL; + } + else if (!S_ISREG (st.st_mode)) + { + terror (_("%s is not a regular file"), name); + return NULL; + } + + fp = fopen (name, "r"); + if (!fp) + { + terror (_("cannot open %s for reading: %s"), name, + strerror (errno)); + return NULL; + } + + istr = emalloc (sizeof *istr); + istr->base.in_name = estrdup (name); + istr->base.in_inter = 0; + istr->base.in_read = instream_file_read; + istr->base.in_close = instream_file_close; + istr->base.in_eq = instream_file_eq; + istr->fp = fp; + istr->dev = st.st_dev; + istr->ino = st.st_ino; + + return (instream_t) istr; +} |