summaryrefslogtreecommitdiff
path: root/src/testgdbm.c
diff options
context:
space:
mode:
authorSam Thursfield <Sam Thursfield>2012-12-27 15:22:58 +0000
committerSam Thursfield <Sam Thursfield>2012-12-27 15:22:58 +0000
commitebd5ad5528d75960e38fa833881388128ac422e8 (patch)
treec3ba28b402a98dcd5b386c3733065465b223ebd0 /src/testgdbm.c
parente48ae579bb2e64987236815ae027aea23057f35f (diff)
downloadgdbm-ebd5ad5528d75960e38fa833881388128ac422e8.tar.gz
Commit gdbm-1.10 tarball to git
gdbm is a dependency of Perl, which is needed to build autoconf, so we cannot build it from git.
Diffstat (limited to 'src/testgdbm.c')
-rw-r--r--src/testgdbm.c510
1 files changed, 224 insertions, 286 deletions
diff --git a/src/testgdbm.c b/src/testgdbm.c
index 0d5317f..b2b9c6c 100644
--- a/src/testgdbm.c
+++ b/src/testgdbm.c
@@ -23,7 +23,6 @@
#include "gdbmdefs.h"
#include "gdbm.h"
-#include "gdbmapp.h"
#include <errno.h>
#include <ctype.h>
@@ -51,11 +50,9 @@ int data_z = 1; /* Data are nul-terminated strings */
#define SIZE_T_MAX ((size_t)-1)
-unsigned input_line;
-
void
-terror (int code, const char *fmt, ...)
+error (int code, const char *fmt, ...)
{
va_list ap;
if (!interactive)
@@ -67,23 +64,7 @@ terror (int code, const char *fmt, ...)
if (code)
exit (code);
}
-
-void
-syntax_error (const char *fmt, ...)
-{
- va_list ap;
- if (!interactive)
- fprintf (stderr, "%s: ", progname);
- fprintf (stderr, "%u: ", input_line);
- va_start (ap, fmt);
- vfprintf (stderr, fmt, ap);
- va_end (ap);
- fputc ('\n', stderr);
- if (!interactive)
- exit (EXIT_USAGE);
-}
-
size_t
bucket_print_lines (hash_bucket *bucket)
@@ -135,23 +116,25 @@ _gdbm_avail_list_size (GDBM_FILE dbf, size_t min_size)
temp = dbf->header->avail.next_block;
size = (((dbf->header->avail.size * sizeof (avail_elem)) >> 1)
+ sizeof (avail_block));
- av_stk = emalloc (size);
+ av_stk = (avail_block *) malloc (size);
+ if (av_stk == NULL)
+ error (2, _("Out of memory"));
/* Traverse the stack. */
while (temp)
{
if (__lseek (dbf, temp, SEEK_SET) != temp)
{
- terror (0, "lseek: %s", strerror (errno));
+ error (0, "lseek: %s", strerror (errno));
break;
}
if ((rc = _gdbm_full_read (dbf, av_stk, size)))
{
if (rc == GDBM_FILE_EOF)
- terror (0, "read: %s", gdbm_strerror (rc));
+ error (0, "read: %s", gdbm_strerror (rc));
else
- terror (0, "read: %s (%s)", gdbm_strerror (rc), strerror (errno));
+ error (0, "read: %s (%s)", gdbm_strerror (rc), strerror (errno));
break;
}
@@ -187,23 +170,25 @@ _gdbm_print_avail_list (FILE *fp, GDBM_FILE dbf)
temp = dbf->header->avail.next_block;
size = (((dbf->header->avail.size * sizeof (avail_elem)) >> 1)
+ sizeof (avail_block));
- av_stk = emalloc (size);
+ av_stk = (avail_block *) malloc (size);
+ if (av_stk == NULL)
+ error (2, _("Out of memory"));
/* Print the stack. */
while (temp)
{
if (__lseek (dbf, temp, SEEK_SET) != temp)
{
- terror (0, "lseek: %s", strerror (errno));
+ error (0, "lseek: %s", strerror (errno));
break;
}
if ((rc = _gdbm_full_read (dbf, av_stk, size)))
{
if (rc == GDBM_FILE_EOF)
- terror (0, "read: %s", gdbm_strerror (rc));
+ error (0, "read: %s", gdbm_strerror (rc));
else
- terror (0, "read: %s (%s)", gdbm_strerror (rc), strerror (errno));
+ error (0, "read: %s (%s)", gdbm_strerror (rc), strerror (errno));
break;
}
@@ -245,6 +230,37 @@ _gdbm_print_bucket_cache (FILE *fp, GDBM_FILE dbf)
fprintf (fp, _("Bucket cache has not been initialized.\n"));
}
+void
+usage ()
+{
+ printf (_("Usage: %s OPTIONS\n"), progname);
+ printf (_("Test and modify a GDBM database.\n"));
+ printf ("\n");
+ printf (_("OPTIONS are:\n\n"));
+ printf (_(" -b SIZE set block size\n"));
+ printf (_(" -c SIZE set cache size\n"));
+ printf (_(" -g FILE operate on FILE instead of `junk.gdbm'\n"));
+ printf (_(" -h print this help summary\n"));
+ printf (_(" -l disable file locking\n"));
+ printf (_(" -m disable file mmap\n"));
+ printf (_(" -n create database\n"));
+ printf (_(" -r open database in read-only mode\n"));
+ printf (_(" -s synchronize to the disk after each write\n"));
+ printf (_(" -v print program version\n"));
+ printf ("\n");
+ printf (_("Report bugs to <%s>.\n"), PACKAGE_BUGREPORT);
+}
+
+void
+version ()
+{
+ printf ("testgdbm (%s) %s\n", PACKAGE_NAME, PACKAGE_VERSION);
+ printf ("Copyright (C) 2007-2011 Free Software Foundation, Inc.\n");
+ printf ("License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>\n");
+ printf ("This is free software: you are free to change and redistribute it.\n");
+ printf ("There is NO WARRANTY, to the extent permitted by law.\n");
+}
+
int
trimnl (char *str)
{
@@ -271,7 +287,7 @@ read_from_file (const char *name, int replace)
fp = fopen (name, "r");
if (!fp)
{
- terror (0, _("cannot open file `%s' for reading: %s"),
+ error (0, _("cannot open file `%s' for reading: %s"),
name, strerror (errno));
return;
}
@@ -282,7 +298,7 @@ read_from_file (const char *name, int replace)
if (!trimnl (buf))
{
- terror (0, _("%s:%d: line too long"), name, line);
+ error (0, _("%s:%d: line too long"), name, line);
continue;
}
@@ -290,7 +306,7 @@ read_from_file (const char *name, int replace)
p = strchr (buf, ' ');
if (!p)
{
- terror (0, _("%s:%d: malformed line"), name, line);
+ error (0, _("%s:%d: malformed line"), name, line);
continue;
}
@@ -301,7 +317,7 @@ read_from_file (const char *name, int replace)
data.dptr = p;
data.dsize = strlen (p) + data_z;
if (gdbm_store (gdbm_file, key, data, flag) != 0)
- terror (0, _("%d: item not inserted: %s"),
+ error (0, _("%d: item not inserted: %s"),
line, gdbm_strerror (gdbm_errno));
}
fclose (fp);
@@ -351,56 +367,49 @@ get_record_count ()
#define ARG_UNUSED __attribute__ ((__unused__))
-#define NARGS 5
+#define NARGS 2
-struct handler_param
-{
- int argc;
- char **argv;
- FILE *fp;
- void *data;
-};
-
/* c - count */
void
-count_handler (struct handler_param *param)
+count_handler (char *arg[NARGS] ARG_UNUSED, FILE *fp,
+ void *call_data ARG_UNUSED)
{
int count = get_record_count ();
- fprintf (param->fp, ngettext ("There is %d item in the database.\n",
- "There are %d items in the database.\n", count),
+ fprintf (fp, ngettext ("There is %d item in the database.\n",
+ "There are %d items in the database.\n", count),
count);
}
/* d key - delete */
void
-delete_handler (struct handler_param *param)
+delete_handler (char *arg[NARGS], FILE *fp, void *call_data ARG_UNUSED)
{
if (key_data.dptr != NULL)
free (key_data.dptr);
- key_data.dptr = strdup (param->argv[0]);
- key_data.dsize = strlen (param->argv[0]) + key_z;
+ key_data.dptr = strdup (arg[0]);
+ key_data.dsize = strlen (arg[0]) + key_z;
if (gdbm_delete (gdbm_file, key_data) != 0)
{
if (gdbm_errno == GDBM_ITEM_NOT_FOUND)
- terror (0, _("Item not found"));
+ error (0, _("Item not found"));
else
- terror (0, _("Can't delete: %s"), gdbm_strerror (gdbm_errno));
+ error (0, _("Can't delete: %s"), gdbm_strerror (gdbm_errno));
}
}
/* f key - fetch */
void
-fetch_handler (struct handler_param *param)
+fetch_handler (char *arg[NARGS], FILE *fp, void *call_data ARG_UNUSED)
{
if (key_data.dptr != NULL)
free (key_data.dptr);
- key_data.dptr = strdup (param->argv[0]);
- key_data.dsize = strlen (param->argv[0]) + key_z;
+ key_data.dptr = strdup (arg[0]);
+ key_data.dsize = strlen (arg[0]) + key_z;
return_data = gdbm_fetch (gdbm_file, key_data);
if (return_data.dptr != NULL)
{
- fprintf (param->fp, "%.*s\n", return_data.dsize, return_data.dptr);
+ fprintf (fp, "%.*s\n", return_data.dsize, return_data.dptr);
free (return_data.dptr);
}
else
@@ -409,15 +418,15 @@ fetch_handler (struct handler_param *param)
/* s key data - store */
void
-store_handler (struct handler_param *param)
+store_handler (char *arg[NARGS], FILE *fp, void *call_data ARG_UNUSED)
{
datum key;
datum data;
- key.dptr = param->argv[0];
- key.dsize = strlen (param->argv[0]) + key_z;
- data.dptr = param->argv[1];
- data.dsize = strlen (param->argv[1]) + data_z;
+ key.dptr = arg[0];
+ key.dsize = strlen (arg[0]) + key_z;
+ data.dptr = arg[1];
+ data.dsize = strlen (arg[1]) + data_z;
if (gdbm_store (gdbm_file, key, data, GDBM_REPLACE) != 0)
fprintf (stderr, _("Item not inserted.\n"));
}
@@ -425,40 +434,40 @@ store_handler (struct handler_param *param)
/* 1 - begin iteration */
void
-firstkey_handler (struct handler_param *param)
+firstkey_handler (char *arg[NARGS], FILE *fp, void *call_data ARG_UNUSED)
{
if (key_data.dptr != NULL)
free (key_data.dptr);
key_data = gdbm_firstkey (gdbm_file);
if (key_data.dptr != NULL)
{
- fprintf (param->fp, "%.*s\n", key_data.dsize, key_data.dptr);
+ fprintf (fp, "%.*s\n", key_data.dsize, key_data.dptr);
return_data = gdbm_fetch (gdbm_file, key_data);
- fprintf (param->fp, "%.*s\n", return_data.dsize, return_data.dptr);
+ fprintf (fp, "%.*s\n", return_data.dsize, return_data.dptr);
free (return_data.dptr);
}
else
- fprintf (param->fp, _("No such item found.\n"));
+ fprintf (fp, _("No such item found.\n"));
}
/* n [key] - next key */
void
-nextkey_handler (struct handler_param *param)
+nextkey_handler (char *arg[NARGS], FILE *fp, void *call_data ARG_UNUSED)
{
- if (param->argv[0])
+ if (arg[0])
{
if (key_data.dptr != NULL)
free (key_data.dptr);
- key_data.dptr = strdup (param->argv[0]);
- key_data.dsize = strlen (param->argv[0]) + key_z;
+ key_data.dptr = strdup (arg[0]);
+ key_data.dsize = strlen (arg[0]) + key_z;
}
return_data = gdbm_nextkey (gdbm_file, key_data);
if (return_data.dptr != NULL)
{
key_data = return_data;
- fprintf (param->fp, "%.*s\n", key_data.dsize, key_data.dptr);
+ fprintf (fp, "%.*s\n", key_data.dsize, key_data.dptr);
return_data = gdbm_fetch (gdbm_file, key_data);
- fprintf (param->fp, "%.*s\n", return_data.dsize, return_data.dptr);
+ fprintf (fp, "%.*s\n", return_data.dsize, return_data.dptr);
free (return_data.dptr);
}
else
@@ -471,7 +480,8 @@ nextkey_handler (struct handler_param *param)
/* r - reorganize */
void
-reorganize_handler (struct handler_param *param ARG_UNUSED)
+reorganize_handler (char *arg[NARGS] ARG_UNUSED, FILE *fp ARG_UNUSED,
+ void *call_data ARG_UNUSED)
{
if (gdbm_reorganize (gdbm_file))
fprintf (stderr, _("Reorganization failed.\n"));
@@ -481,23 +491,23 @@ reorganize_handler (struct handler_param *param ARG_UNUSED)
/* A - print available list */
int
-avail_begin (struct handler_param *param ARG_UNUSED, size_t *exp_count)
-{
+avail_begin (char *arg[NARGS], size_t *exp_count, void **data)
+{
if (exp_count)
*exp_count = _gdbm_avail_list_size (gdbm_file, SIZE_T_MAX);
return 0;
}
void
-avail_handler (struct handler_param *param)
+avail_handler (char *arg[NARGS] ARG_UNUSED, FILE *fp,
+ void *call_data ARG_UNUSED)
{
- _gdbm_print_avail_list (param->fp, gdbm_file);
+ _gdbm_print_avail_list (fp, gdbm_file);
}
/* C - print current bucket */
int
-print_current_bucket_begin (struct handler_param *param ARG_UNUSED,
- size_t *exp_count)
+print_current_bucket_begin (char *arg[NARGS], size_t *exp_count, void **data)
{
if (exp_count)
*exp_count = bucket_print_lines (gdbm_file->bucket) + 3;
@@ -505,12 +515,13 @@ print_current_bucket_begin (struct handler_param *param ARG_UNUSED,
}
void
-print_current_bucket_handler (struct handler_param *param)
+print_current_bucket_handler (char *arg[NARGS] ARG_UNUSED, FILE *fp,
+ void *call_data ARG_UNUSED)
{
- print_bucket (param->fp, gdbm_file->bucket, _("Current bucket"));
- fprintf (param->fp, _("\n current directory entry = %d.\n"),
+ print_bucket (fp, gdbm_file->bucket, _("Current bucket"));
+ fprintf (fp, _("\n current directory entry = %d.\n"),
gdbm_file->bucket_dir);
- fprintf (param->fp, _(" current bucket address = %lu.\n"),
+ fprintf (fp, _(" current bucket address = %lu.\n"),
(unsigned long) gdbm_file->cache_entry->ca_adr);
}
@@ -540,11 +551,11 @@ getnum (int *pnum, char *arg, char **endp)
/* B num - print a bucket and set is a current one.
Uses print_current_bucket_handler */
int
-print_bucket_begin (struct handler_param *param, size_t *exp_count)
+print_bucket_begin (char *arg[NARGS], size_t *exp_count, void **data ARG_UNUSED)
{
int temp;
- if (getnum (&temp, param->argv[0], NULL))
+ if (getnum (&temp, arg[0], NULL))
return 1;
if (temp >= gdbm_file->header->dir_size / 4)
@@ -561,7 +572,7 @@ print_bucket_begin (struct handler_param *param, size_t *exp_count)
/* D - print hash directory */
int
-print_dir_begin (struct handler_param *param ARG_UNUSED, size_t *exp_count)
+print_dir_begin (char *arg[NARGS], size_t *exp_count, void **data ARG_UNUSED)
{
if (exp_count)
*exp_count = gdbm_file->header->dir_size / 4 + 3;
@@ -569,22 +580,22 @@ print_dir_begin (struct handler_param *param ARG_UNUSED, size_t *exp_count)
}
void
-print_dir_handler (struct handler_param *param)
+print_dir_handler (char *arg[NARGS] ARG_UNUSED, FILE *out,
+ void *call_data ARG_UNUSED)
{
int i;
- fprintf (param->fp, _("Hash table directory.\n"));
- fprintf (param->fp, _(" Size = %d. Bits = %d. \n\n"),
+ fprintf (out, _("Hash table directory.\n"));
+ fprintf (out, _(" Size = %d. Bits = %d. \n\n"),
gdbm_file->header->dir_size, gdbm_file->header->dir_bits);
for (i = 0; i < gdbm_file->header->dir_size / 4; i++)
- fprintf (param->fp, " %10d: %12lu\n",
- i, (unsigned long) gdbm_file->dir[i]);
+ fprintf (out, " %10d: %12lu\n", i, (unsigned long) gdbm_file->dir[i]);
}
/* F - print file handler */
int
-print_header_begin (struct handler_param *param ARG_UNUSED, size_t *exp_count)
+print_header_begin (char *arg[NARGS], size_t *exp_count, void **data ARG_UNUSED)
{
if (exp_count)
*exp_count = 14;
@@ -592,10 +603,8 @@ print_header_begin (struct handler_param *param ARG_UNUSED, size_t *exp_count)
}
void
-print_header_handler (struct handler_param *param)
+print_header_handler (char *arg[NARGS] ARG_UNUSED, FILE *fp, void *call_data)
{
- FILE *fp = param->fp;
-
fprintf (fp, _("\nFile Header: \n\n"));
fprintf (fp, _(" table = %lu\n"),
(unsigned long) gdbm_file->header->dir);
@@ -615,18 +624,18 @@ print_header_handler (struct handler_param *param)
/* H key - hash the key */
void
-hash_handler (struct handler_param *param)
+hash_handler (char *arg[NARGS], FILE *fp, void *call_data)
{
datum key;
- key.dptr = param->argv[0];
- key.dsize = strlen (param->argv[0]) + key_z;
- fprintf (param->fp, _("hash value = %x. \n"), _gdbm_hash (key));
+ key.dptr = arg[0];
+ key.dsize = strlen (arg[0]) + key_z;
+ fprintf (fp, _("hash value = %x. \n"), _gdbm_hash (key));
}
/* K - print the bucket cache */
int
-print_cache_begin (struct handler_param *param ARG_UNUSED, size_t *exp_count)
+print_cache_begin (char *arg[NARGS], size_t *exp_count, void **data ARG_UNUSED)
{
if (exp_count)
*exp_count = gdbm_file->bucket_cache ? gdbm_file->cache_size + 1 : 1;
@@ -634,29 +643,30 @@ print_cache_begin (struct handler_param *param ARG_UNUSED, size_t *exp_count)
}
void
-print_cache_handler (struct handler_param *param)
+print_cache_handler (char *arg[NARGS] ARG_UNUSED, FILE *fp,
+ void *call_data ARG_UNUSED)
{
- _gdbm_print_bucket_cache (param->fp, gdbm_file);
+ _gdbm_print_bucket_cache (fp, gdbm_file);
}
/* V - print GDBM version */
void
-print_version_handler (struct handler_param *param)
+print_version_handler (char *arg[NARGS] ARG_UNUSED, FILE *fp,
+ void *call_data ARG_UNUSED)
{
- fprintf (param->fp, "%s\n", gdbm_version);
+ fprintf (fp, "%s\n", gdbm_version);
}
/* < file [replace] - read entries from file and store */
void
-read_handler (struct handler_param *param)
+read_handler (char *arg[NARGS], FILE *fp, void *call_data ARG_UNUSED)
{
- read_from_file (param->argv[0],
- param->argv[1] && strcmp (param->argv[1], "replace") == 0);
+ read_from_file (arg[0], arg[1] && strcmp (arg[1], "replace") == 0);
}
/* l - List all entries */
int
-list_begin (struct handler_param *param ARG_UNUSED, size_t *exp_count)
+list_begin (char *arg[NARGS], size_t *exp_count, void **data ARG_UNUSED)
{
if (exp_count)
*exp_count = get_record_count ();
@@ -664,7 +674,7 @@ list_begin (struct handler_param *param ARG_UNUSED, size_t *exp_count)
}
void
-list_handler (struct handler_param *param)
+list_handler (char *arg[NARGS] ARG_UNUSED, FILE *fp, void *call_data)
{
datum key;
datum data;
@@ -676,10 +686,10 @@ list_handler (struct handler_param *param)
data = gdbm_fetch (gdbm_file, key);
if (!data.dptr)
- terror (0, _("cannot fetch data (key %.*s)"), key.dsize, key.dptr);
+ error (0, _("cannot fetch data (key %.*s)"), key.dsize, key.dptr);
else
{
- fprintf (param->fp, "%.*s %.*s\n", key.dsize, key.dptr, data.dsize,
+ fprintf (fp, "%.*s %.*s\n", key.dsize, key.dptr, data.dsize,
data.dptr);
free (data.dptr);
}
@@ -690,84 +700,39 @@ list_handler (struct handler_param *param)
/* q - quit the program */
void
-quit_handler (struct handler_param *param ARG_UNUSED)
+quit_handler (char *arg[NARGS] ARG_UNUSED, FILE *fp ARG_UNUSED,
+ void *call_data ARG_UNUSED)
{
if (gdbm_file != NULL)
gdbm_close (gdbm_file);
- exit (EXIT_OK);
+ exit (0);
}
/* e file [truncate] - export to a flat file format */
void
-export_handler (struct handler_param *param)
+export_handler (char *arg[NARGS], FILE *fp, void *call_data ARG_UNUSED)
{
- int format = GDBM_DUMP_FMT_ASCII;
int flags = GDBM_WRCREAT;
- int i;
-
- for (i = 1; i < param->argc; i++)
- {
- if (strcmp (param->argv[i], "truncate") == 0)
- flags = GDBM_NEWDB;
- else if (strcmp (param->argv[i], "binary") == 0)
- format = GDBM_DUMP_FMT_BINARY;
- else if (strcmp (param->argv[i], "ascii") == 0)
- format = GDBM_DUMP_FMT_ASCII;
- else
- {
- syntax_error (_("unrecognized argument: %s"), param->argv[i]);
- return;
- }
- }
- if (gdbm_dump (gdbm_file, param->argv[0], format, flags, 0600))
- {
- terror (0, _("error dumping database: %s"), gdbm_strerror (gdbm_errno));
- }
+ if (arg[1] != NULL && strcmp (arg[1], "truncate") == 0)
+ flags = GDBM_NEWDB;
+
+ if (gdbm_export (gdbm_file, arg[0], flags, 0600) == -1)
+ error (0, _("gdbm_export failed, %s"), gdbm_strerror (gdbm_errno));
}
/* i file [replace] - import from a flat file */
void
-import_handler (struct handler_param *param)
+import_handler (char *arg[NARGS], FILE *fp, void *call_data ARG_UNUSED)
{
int flag = GDBM_INSERT;
- unsigned long err_line;
- int meta_mask = 0;
- int i;
-
- for (i = 1; i < param->argc; i++)
- {
- if (strcmp (param->argv[i], "replace") == 0)
- flag = GDBM_REPLACE;
- else if (strcmp (param->argv[i], "nometa") == 0)
- meta_mask = GDBM_META_MASK_MODE | GDBM_META_MASK_OWNER;
- else
- {
- syntax_error (_("unrecognized argument: %s"), param->argv[i]);
- return;
- }
- }
- if (gdbm_load (&gdbm_file, param->argv[0], flag, meta_mask, &err_line))
- {
- switch (gdbm_errno)
- {
- case GDBM_ERR_FILE_OWNER:
- case GDBM_ERR_FILE_MODE:
- terror (0, _("error restoring metadata: %s (%s)"),
- gdbm_strerror (gdbm_errno), strerror (errno));
- break;
-
- default:
- if (err_line)
- terror (0, "%s:%lu: %s", param->argv[0], err_line,
- gdbm_strerror (gdbm_errno));
- else
- terror (0, _("cannot load from %s: %s"), param->argv[0],
- gdbm_strerror (gdbm_errno));
- }
- }
+ if (arg[1] != NULL && strcmp(arg[1], "replace") == 0)
+ flag = GDBM_REPLACE;
+
+ if (gdbm_import (gdbm_file, arg[0], flag) == -1)
+ error (0, _("gdbm_import failed, %s"), gdbm_strerror (gdbm_errno));
}
static const char *
@@ -778,40 +743,43 @@ boolstr (int val)
/* S - print current program status */
void
-status_handler (struct handler_param *param)
+status_handler (char *arg[NARGS] ARG_UNUSED, FILE *fp,
+ void *call_data ARG_UNUSED)
{
- fprintf (param->fp, _("Database file: %s\n"), file_name);
- fprintf (param->fp, _("Zero terminated keys: %s\n"), boolstr (key_z));
- fprintf (param->fp, _("Zero terminated data: %s\n"), boolstr (data_z));
+ fprintf (fp, _("Database file: %s\n"), file_name);
+ fprintf (fp, _("Zero terminated keys: %s\n"), boolstr (key_z));
+ fprintf (fp, _("Zero terminated data: %s\n"), boolstr (data_z));
}
/* z - toggle key nul-termination */
void
-key_z_handler (struct handler_param *param)
+key_z_handler (char *arg[NARGS] ARG_UNUSED, FILE *fp,
+ void *call_data ARG_UNUSED)
{
key_z = !key_z;
- fprintf (param->fp, _("Zero terminated keys: %s\n"), boolstr (key_z));
+ fprintf (fp, _("Zero terminated keys: %s\n"), boolstr (key_z));
}
/* Z - toggle data nul-termination */
void
-data_z_handler (struct handler_param *param)
+data_z_handler (char *arg[NARGS] ARG_UNUSED, FILE *fp,
+ void *call_data ARG_UNUSED)
{
data_z = !data_z;
- fprintf (param->fp, _("Zero terminated data: %s\n"), boolstr (data_z));
+ fprintf (fp, "Zero terminated data: %s\n", boolstr (data_z));
}
-void help_handler (struct handler_param *param);
-int help_begin (struct handler_param *param, size_t *exp_count);
+void help_handler (char *arg[NARGS], FILE *fp, void *call_data);
+int help_begin (char *arg[NARGS], size_t *exp_count, void **data);
struct command
{
char *name; /* Command name */
size_t minlen; /* Minimal unambiguous length */
int abbrev; /* Single-letter shortkey (optional) */
- int (*begin) (struct handler_param *param, size_t *);
- void (*handler) (struct handler_param *param);
+ int (*begin) (char *[NARGS], size_t *, void **);
+ void (*handler) (char *[NARGS], FILE *fp, void *call_data);
void (*end) (void *data);
char *args[NARGS];
char *doc;
@@ -827,13 +795,13 @@ struct command command_tab[] = {
{ N_("key"), NULL, }, N_("delete") },
{ "export", 0, 'e',
NULL, export_handler, NULL,
- { N_("file"), "[truncate]", "[binary|ascii]" }, N_("export") },
+ { N_("file"), "[truncate]", }, N_("export") },
{ "fetch", 0, 'f',
NULL, fetch_handler, NULL,
{ N_("key"), NULL }, N_("fetch") },
{ "import", 0, 'i',
NULL, import_handler, NULL,
- { N_("file"), "[replace]", "[nometa]" }, N_("import") },
+ { N_("file"), "[replace]", }, N_("import") },
{ "list", 0, 'l',
list_begin, list_handler, NULL,
{ NULL, NULL }, N_("list") },
@@ -952,7 +920,7 @@ set_minimal_abbreviations ()
#define CMDCOLS 30
int
-help_begin (struct handler_param *param ARG_UNUSED, size_t *exp_count)
+help_begin (char *arg[NARGS], size_t *exp_count, void **data)
{
if (exp_count)
*exp_count = sizeof (command_tab) / sizeof (command_tab[0]) + 1;
@@ -960,10 +928,9 @@ help_begin (struct handler_param *param ARG_UNUSED, size_t *exp_count)
}
void
-help_handler (struct handler_param *param)
+help_handler (char *arg[NARGS], FILE *fp, void *call_data)
{
struct command *cmd;
- FILE *fp = param->fp;
for (cmd = command_tab; cmd->name; cmd++)
{
@@ -1029,26 +996,8 @@ getword (char *s, char **endp)
}
/* The test program allows one to call all the routines plus the hash function.
- The commands are single letter commands. The user is prompted for missing
- pieces of information. See the help command (?) for a list of all
- commands. */
-
-char *parseopt_program_doc = "Test and modify a GDBM database";
-char *parseopt_program_args = N_("FILE");
-
-struct gdbm_option optab[] = {
- { 'b', "block-size", N_("SIZE"), N_("set block size") },
- { 'c', "cache-size", N_("SIZE"), N_("set cache size") },
- { 'g', NULL, "FILE", NULL, PARSEOPT_HIDDEN },
- { 'l', "no-lock", NULL, N_("disable file locking") },
- { 'm', "no-mmap", NULL, N_("disable file mmap") },
- { 'n', "newdb", NULL, N_("create database") },
- { 'r', "read-only", NULL, N_("open database in read-only mode") },
- { 's', "synchronize", NULL, N_("synchronize to disk after each write") },
- { 0 }
-};
-
-#define ARGINC 16
+ The commands are single letter commands. The user is prompted for all other
+ information. See the help command (?) for a list of all commands. */
int
main (int argc, char *argv[])
@@ -1064,10 +1013,11 @@ main (int argc, char *argv[])
int flags = 0;
char *pager = getenv ("PAGER");
- struct handler_param param;
- size_t argmax;
-
- set_progname (argv[0]);
+ progname = strrchr (argv[0], '/');
+ if (progname)
+ progname++;
+ else
+ progname = argv[0];
#ifdef HAVE_SETLOCALE
setlocale (LC_ALL, "");
@@ -1077,11 +1027,29 @@ main (int argc, char *argv[])
set_minimal_abbreviations ();
- for (opt = parseopt_first (argc, argv, optab);
- opt != EOF;
- opt = parseopt_next ())
+ /* Argument checking. */
+ if (argc == 2)
+ {
+ if (strcmp (argv[1], "--help") == 0)
+ {
+ usage ();
+ exit (0);
+ }
+ else if (strcmp (argv[1], "--version") == 0)
+ {
+ version ();
+ exit (0);
+ }
+ }
+
+ opterr = 0;
+ while ((opt = getopt (argc, argv, "lmsrnc:b:g:hv")) != -1)
switch (opt)
{
+ case 'h':
+ usage ();
+ exit (0);
+
case 'l':
flags = flags | GDBM_NOLOCK;
break;
@@ -1092,21 +1060,21 @@ main (int argc, char *argv[])
case 's':
if (reader)
- terror (EXIT_USAGE, _("-s is incompatible with -r"));
+ error (2, _("-s is incompatible with -r"));
flags = flags | GDBM_SYNC;
break;
case 'r':
if (newdb)
- terror (EXIT_USAGE, _("-r is incompatible with -n"));
+ error (2, _("-r is incompatible with -n"));
reader = TRUE;
break;
case 'n':
if (reader)
- terror (EXIT_USAGE, _("-n is incompatible with -r"));
+ error (2, _("-n is incompatible with -r"));
newdb = TRUE;
break;
@@ -1123,19 +1091,15 @@ main (int argc, char *argv[])
file_name = optarg;
break;
+ case 'v':
+ version ();
+ exit (0);
+
default:
- terror (EXIT_USAGE,
- _("unknown option; try `%s -h' for more info\n"), progname);
+ error (2, _("unknown option; try `%s -h' for more info\n"), progname);
}
- argc -= optind;
- argv += optind;
-
- if (argc > 1)
- terror (EXIT_USAGE, _("too many arguments"));
- if (argc == 1)
- file_name = argv[0];
- else
+ if (file_name == NULL)
file_name = "junk.gdbm";
/* Initialize variables. */
@@ -1156,12 +1120,11 @@ main (int argc, char *argv[])
gdbm_open (file_name, block_size, GDBM_WRCREAT | flags, 00664, NULL);
}
if (gdbm_file == NULL)
- terror (EXIT_FATAL, _("gdbm_open failed: %s"), gdbm_strerror (gdbm_errno));
+ error (2, _("gdbm_open failed: %s"), gdbm_strerror (gdbm_errno));
if (gdbm_setopt (gdbm_file, GDBM_CACHESIZE, &cache_size, sizeof (int)) ==
-1)
- terror (EXIT_FATAL, _("gdbm_setopt failed: %s"),
- gdbm_strerror (gdbm_errno));
+ error (2, _("gdbm_setopt failed: %s"), gdbm_strerror (gdbm_errno));
signal (SIGPIPE, SIG_IGN);
@@ -1169,23 +1132,17 @@ main (int argc, char *argv[])
if (interactive)
printf (_("\nWelcome to the gdbm test program. Type ? for help.\n\n"));
- memset (&param, 0, sizeof (param));
- argmax = 0;
-
while (1)
{
int i;
char *p, *sp;
- char argbuf[128];
+ char argbuf[NARGS][128];
+ char *args[NARGS];
struct command *cmd;
+ void *call_data;
size_t expected_lines, *expected_lines_ptr;
- FILE *pagfp = NULL;
-
- for (i = 0; i < param.argc; i++)
- free (param.argv[i]);
+ FILE *out;
- input_line++;
-
if (interactive)
{
printf ("%s", prompt);
@@ -1205,85 +1162,66 @@ main (int argc, char *argv[])
cmd = find_command (p);
if (!cmd)
{
- terror (0,
+ error (0,
interactive ? _("Invalid command. Try ? for help.") :
_("Unknown command"));
continue;
}
- for (i = 0; cmd->args[i]; i++)
+ memset (args, 0, sizeof (args));
+ for (i = 0; i < NARGS && cmd->args[i]; i++)
{
- char *arg = cmd->args[i];
-
- p = getword (sp, &sp);
+ p = i < NARGS-1 ? getword (sp, &sp) : sp;
if (!*p)
{
+ char *arg = cmd->args[i];
if (*arg == '[')
/* Optional argument */
break;
if (!interactive)
- syntax_error (_("%s: not enough arguments"), cmd->name);
+ error (1, _("%s: not enough arguments"), cmd->name);
+
+
printf ("%s? ", arg);
- if (fgets (argbuf, sizeof argbuf, stdin) == NULL)
- terror (EXIT_USAGE, _("unexpected eof"));
+ if (fgets (argbuf[i], sizeof argbuf[i], stdin) == NULL)
+ error (1, _("unexpected eof"));
- trimnl (argbuf);
- p = argbuf;
- }
-
- if (i >= argmax)
- {
- argmax += ARGINC;
- param.argv = erealloc (param.argv,
- sizeof (param.argv[0]) * argmax);
+ trimnl (argbuf[i]);
+ args[i] = argbuf[i];
}
- param.argv[i] = estrdup (p);
- }
+ else
+ args[i] = p;
+ }
- if (*sp)
- {
- syntax_error (_("%s: too many arguments"), cmd->name);
- continue;
- }
-
/* Prepare for calling the handler */
- param.argc = i;
- param.fp = NULL;
- param.data = NULL;
- pagfp = NULL;
-
+ call_data = NULL;
expected_lines = 0;
expected_lines_ptr = (interactive && pager) ? &expected_lines : NULL;
- if (cmd->begin && cmd->begin (&param, expected_lines_ptr))
+ out = NULL;
+ if (cmd->begin && cmd->begin (args, expected_lines_ptr, &call_data))
continue;
if (pager && expected_lines > get_screen_lines ())
{
- pagfp = popen (pager, "w");
- if (pagfp)
- param.fp = pagfp;
- else
+ out = popen (pager, "w");
+ if (!out)
{
- terror (0, _("cannot run pager `%s': %s"), pager,
- strerror (errno));
+ error (0, _("cannot run pager `%s': %s"), pager,
+ strerror (errno));
pager = NULL;
- param.fp = stdout;
- }
+ }
}
- else
- param.fp = stdout;
- cmd->handler (&param);
+ cmd->handler (args, out ? out : stdout, call_data);
if (cmd->end)
- cmd->end (param.data);
- else if (param.data)
- free (param.data);
-
- if (pagfp)
- pclose (pagfp);
+ cmd->end (call_data);
+ else if (call_data)
+ free (call_data);
+ if (out)
+ pclose (out);
}
/* Quit normally. */
- quit_handler (NULL);
+ quit_handler (NULL, stdout, NULL);
return 0;
}