aboutsummaryrefslogtreecommitdiff
path: root/src/gdbmtool.c
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2013-05-14 06:22:55 +0000
committerSergey Poznyakoff <gray@gnu.org.ua>2013-05-14 06:22:55 +0000
commit10201217d141314a78a7937027bfdbdb7c994a43 (patch)
tree0ce888c1ef130a9d6847d045cac9b04c3a1590dc /src/gdbmtool.c
parent6d66bc4877a319d0f6400f5058be47f221e731da (diff)
downloadgdbm-10201217d141314a78a7937027bfdbdb7c994a43.tar.gz
gdbm-10201217d141314a78a7937027bfdbdb7c994a43.tar.bz2
Implement rc files and "source" command; improve lexical analyzer.
* src/gdbmtool.c (interactive): Move to lex.l; (mkfilename, tildexpand): New functions. (command_tab) <source>: New command. (main): Source rc file, if present. * src/gdbmtool.h (setsource): Change return type and signature. * src/lex.l: Implement context stack. Change DEF to be an exclusive state. * src/gdbmapp.h (estrdup): Argument is const. * src/mem.c: Likewise.
Diffstat (limited to 'src/gdbmtool.c')
-rw-r--r--src/gdbmtool.c127
1 files changed, 111 insertions, 16 deletions
diff --git a/src/gdbmtool.c b/src/gdbmtool.c
index 5e672b2..905c3fb 100644
--- a/src/gdbmtool.c
+++ b/src/gdbmtool.c
@@ -22,6 +22,7 @@
#include <errno.h>
#include <ctype.h>
#include <signal.h>
+#include <pwd.h>
#include <sys/ioctl.h>
#ifdef HAVE_SYS_TERMIOS_H
# include <sys/termios.h>
@@ -31,12 +32,11 @@
# include <locale.h>
#endif
-char *file_name = NULL; /* Database file name */
+char *file_name = NULL; /* Database file name */
GDBM_FILE gdbm_file = NULL; /* Database to operate upon */
-int interactive; /* Are we running in interactive mode? */
-datum key_data; /* Current key */
-datum return_data; /* Current data */
-int quiet_option = 0; /* Omit usual welcome banner at startup */
+datum key_data; /* Current key */
+datum return_data; /* Current data */
+int quiet_option = 0; /* Omit the usual welcome banner at startup */
#define SIZE_T_MAX ((size_t)-1)
@@ -56,7 +56,57 @@ terror (int code, const char *fmt, ...)
if (code)
exit (code);
}
+
+char *
+mkfilename (const char *dir, const char *file, const char *suf)
+{
+ char *tmp;
+ size_t dirlen = strlen (dir);
+ size_t suflen = suf ? strlen (suf) : 0;
+ size_t fillen = strlen (file);
+ size_t len;
+
+ while (dirlen > 0 && dir[dirlen-1] == '/')
+ dirlen--;
+
+ len = dirlen + (dir[0] ? 1 : 0) + fillen + suflen;
+ tmp = emalloc (len + 1);
+ memcpy (tmp, dir, dirlen);
+ if (dir[0])
+ tmp[dirlen++] = '/';
+ memcpy (tmp + dirlen, file, fillen);
+ if (suf)
+ memcpy (tmp + dirlen + fillen, suf, suflen);
+ tmp[len] = 0;
+ return tmp;
+}
+
+char *
+tildexpand (char *s)
+{
+ if (s[0] == '~')
+ {
+ char *p = s + 1;
+ size_t len = strcspn (p, "/");
+ struct passwd *pw;
+ if (len == 0)
+ pw = getpwuid (getuid ());
+ else
+ {
+ char *user = emalloc (len + 1);
+
+ memcpy (user, p, len);
+ user[len] = 0;
+ pw = getpwnam (user);
+ free (user);
+ }
+ if (pw)
+ return mkfilename (pw->pw_dir, p + len + 1, NULL);
+ }
+ return estrdup (s);
+}
+
size_t
bucket_print_lines (hash_bucket *bucket)
@@ -698,6 +748,16 @@ status_handler (struct handler_param *param)
fprintf (param->fp, _("Database file: %s\n"), file_name);
}
+void
+source_handler (struct handler_param *param)
+{
+ char *fname = tildexpand (param->argv[0]->v.string);
+ if (setsource (fname, 0) == 0)
+ yyparse ();
+ free (fname);
+}
+
+
void help_handler (struct handler_param *param);
int help_begin (struct handler_param *param, size_t *exp_count);
@@ -810,6 +870,10 @@ struct command command_tab[] = {
{ { "key|content", ARG_STRING },
{ "{ field-list }", ARG_STRING },
{ NULL } }, N_("define structure") },
+ { S(source), T_CMD,
+ NULL, source_handler, NULL,
+ { { "file", ARG_STRING },
+ { NULL } }, N_("source command script") },
#undef S
{ 0 }
};
@@ -1279,12 +1343,44 @@ run_command (struct command *cmd, struct gdbmarglist *arglist)
return 0;
}
-
+
+static void
+source_rcfile ()
+{
+ if (access (GDBMTOOLRC, R_OK) == 0)
+ {
+ if (setsource (GDBMTOOLRC, 0) == 0)
+ yyparse ();
+ }
+ else
+ {
+ char *fname;
+ char *p = getenv ("HOME");
+ if (!p)
+ {
+ struct passwd *pw = getpwuid (getuid ());
+ if (!pw)
+ {
+ terror (0, _("cannot find home directory"));
+ return;
+ }
+ p = pw->pw_dir;
+ }
+ fname = mkfilename (p, GDBMTOOLRC, NULL);
+ if (access (fname, R_OK) == 0)
+ {
+ if (setsource (fname, 0) == 0)
+ yyparse ();
+ }
+ free (fname);
+ }
+}
+
int
main (int argc, char *argv[])
{
- char cmdbuf[1000];
-
+ int intr;
+
int cache_size = DEFAULT_CACHESIZE;
int block_size = 0;
@@ -1369,7 +1465,7 @@ main (int argc, char *argv[])
file_name = "junk.gdbm";
/* Initialize variables. */
- interactive = isatty (0);
+ intr = isatty (0);
dsdef[DS_KEY] = dsegm_new_field (datadef_lookup ("string"), NULL, 1);
dsdef[DS_CONTENT] = dsegm_new_field (datadef_lookup ("string"), NULL, 1);
@@ -1397,16 +1493,15 @@ main (int argc, char *argv[])
signal (SIGPIPE, SIG_IGN);
+ memset (&param, 0, sizeof (param));
+ argmax = 0;
+
/* Welcome message. */
- if (interactive && !quiet_option)
+ if (intr && !quiet_option)
printf (_("\nWelcome to the gdbm tool. Type ? for help.\n\n"));
- memset (&param, 0, sizeof (param));
- argmax = 0;
+ source_rcfile ();
- setsource ("stdin", stdin);
- //FIXME
+ setsource ("-", intr);
return yyparse ();
-
- return 0;
}

Return to:

Send suggestions and report system problems to the System administrator.