diff options
author | Sam Thursfield <Sam Thursfield> | 2012-12-27 15:22:58 +0000 |
---|---|---|
committer | Sam Thursfield <Sam Thursfield> | 2012-12-27 15:22:58 +0000 |
commit | ebd5ad5528d75960e38fa833881388128ac422e8 (patch) | |
tree | c3ba28b402a98dcd5b386c3733065465b223ebd0 /src/testgdbm.c | |
parent | e48ae579bb2e64987236815ae027aea23057f35f (diff) | |
download | gdbm-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.c | 510 |
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 (¶m, 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 (¶m, 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 (¶m); + 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; } |