Fixed bug #668: save command line history for yaz-client. The history
authorAdam Dickmeiss <adam@indexdata.dk>
Wed, 24 Jan 2007 11:50:18 +0000 (11:50 +0000)
committerAdam Dickmeiss <adam@indexdata.dk>
Wed, 24 Jan 2007 11:50:18 +0000 (11:50 +0000)
is saved in ~/.yazclient.history .

NEWS
client/Makefile.am
client/admin.h
client/client.c
client/fhistory.c [new file with mode: 0644]
client/fhistory.h [new file with mode: 0644]
doc/yaz-client-man.xml
win/makefile

diff --git a/NEWS b/NEWS
index 8594aae..51ee56a 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,5 @@
+Fixed bug #668: save command line history for yaz-client.
+
 Fixed bug #830: pkg-config support.
 
 --- 2.1.48 2007/01/23
index a5241d2..fb0e32d 100644 (file)
@@ -1,6 +1,6 @@
 ## Copyright (C) 1995-2007, Index Data
 ## All rights reserved.
-## $Id: Makefile.am,v 1.28 2007-01-03 08:42:13 adam Exp $
+## $Id: Makefile.am,v 1.29 2007-01-24 11:50:18 adam Exp $
 
 
 bin_PROGRAMS=yaz-client 
@@ -8,7 +8,7 @@ EXTRA_PROGRAMS=bertorture
 
 EXTRA_DIST = default.bib
 
-COMMON=admin.c admin.h tabcomplete.c tabcomplete.h
+COMMON=admin.c admin.h tabcomplete.c tabcomplete.h fhistory.c fhistory.h
 yaz_client_SOURCES=client.c $(COMMON)
 
 AM_CFLAGS=$(THREAD_CFLAGS)
index 0a87a11..0d0ec2c 100644 (file)
@@ -1,8 +1,8 @@
 /*
- * Copyright (C) 1995-2005, Index Data ApS
+ * Copyright (C) 1995-2007, Index Data ApS
  * See the file LICENSE for details.
  *
- * $Id: admin.h,v 1.9 2005-06-25 15:46:01 adam Exp $
+ * $Id: admin.h,v 1.10 2007-01-24 11:50:18 adam Exp $
  */
 
 int cmd_adm_reindex(const char* arg);
index 39c1078..1055bff 100644 (file)
@@ -2,7 +2,7 @@
  * Copyright (C) 1995-2007, Index Data ApS
  * See the file LICENSE for details.
  *
- * $Id: client.c,v 1.324 2007-01-24 09:54:04 adam Exp $
+ * $Id: client.c,v 1.325 2007-01-24 11:50:18 adam Exp $
  */
 /** \file client.c
  *  \brief yaz-client program
 
 #include "admin.h"
 #include "tabcomplete.h"
+#include "fhistory.h"
 
 #define C_PROMPT "Z> "
 
+static file_history_t file_history = 0;
+
 static char *sru_method = "soap";
 static char *codeset = 0;               /* character set for output */
 static int hex_dump = 0;
@@ -2824,11 +2827,18 @@ static int cmd_show(const char *arg)
     return 2;
 }
 
+void exit_client(int code)
+{
+    file_history_save(file_history);
+    file_history_destroy(&file_history);
+    exit(code);
+}
+
 int cmd_quit(const char *arg)
 {
     printf("See you later, alligator.\n");
     xmalloc_trav ("");
-    exit(0);
+    exit_client(0);
     return 0;
 }
 
@@ -3712,24 +3722,24 @@ void source_rcfile(void)
 {
     /*  Look for a $HOME/.yazclientrc and source it if it exists */
     struct stat statbuf;
-    char buffer[1000];
-    char* homedir=getenv("HOME");
+    char fname[1000];
+    char* homedir = getenv("HOME");
 
-    if( homedir ) {
-        
-        sprintf(buffer,"%s/.yazclientrc",homedir);
+    sprintf(fname, "%.500s%s%s", homedir ? homedir : "",
+            homedir ? "/" : "",
+            ".yazclientrc");
 
-        if(stat(buffer,&statbuf)==0) {
-            cmd_source(buffer, 0 );
-        }
-        
-    };
-    
-    if(stat(".yazclientrc",&statbuf)==0) {
-        cmd_source(".yazclientrc", 0 );
-    }
+    if (stat(fname,&statbuf)==0)
+        cmd_source(fname, 0 );
 }
 
+void add_to_readline_history(void *client_data, const char *line)
+{
+#if HAVE_READLINE_HISTORY_H
+    if (strlen(line))
+        add_history(line);
+#endif
+}
 
 static void initialize(void)
 {
@@ -3768,6 +3778,10 @@ static void initialize(void)
     }
     
     source_rcfile();
+
+    file_history = file_history_new();
+    file_history_load(file_history);
+    file_history_trav(file_history, 0, add_to_readline_history);
 }
 
 
@@ -4709,7 +4723,7 @@ static void client(void)
             if (*line_in)
                 add_history(line_in);
 #endif
-            strncpy(line, line_in, 10239);
+            strncpy(line, line_in, sizeof(line)-1);
             free(line_in);
         }
 #endif 
@@ -4718,11 +4732,13 @@ static void client(void)
             char *end_p;
             printf (C_PROMPT);
             fflush(stdout);
-            if (!fgets(line, 10239, stdin))
+            if (!fgets(line, sizeof(line)-1, stdin))
                 break;
             if ((end_p = strchr (line, '\n')))
                 *end_p = '\0';
         }
+        if (isatty(0))
+            file_history_add_line(file_history, line);
         process_cmd_line(line);
     }
 }
@@ -4881,8 +4897,9 @@ int main(int argc, char **argv)
 #endif
         xfree(open_command);
     }
-    client ();
-    exit (0);
+    client();
+    exit_client(0);
+    return 0;
 }
 /*
  * Local variables:
diff --git a/client/fhistory.c b/client/fhistory.c
new file mode 100644 (file)
index 0000000..0020f76
--- /dev/null
@@ -0,0 +1,129 @@
+/* 
+ * Copyright (C) 1995-2007, Index Data ApS
+ * See the file LICENSE for details.
+ *
+ * $Id: fhistory.c,v 1.1 2007-01-24 11:50:18 adam Exp $
+ */
+/** \file fhistory.c
+ *  \brief file history implementation
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <time.h>
+#include <ctype.h>
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+#include "fhistory.h"
+
+
+struct file_history {
+    WRBUF wr;
+};
+
+file_history_t file_history_new()
+{
+    file_history_t fh = xmalloc(sizeof(*fh));
+    fh->wr = wrbuf_alloc();
+    return fh;
+}
+
+void file_history_destroy(file_history_t *fhp)
+{
+    if (*fhp)
+    {
+        wrbuf_destroy((*fhp)->wr);
+        xfree(*fhp);
+        *fhp = 0;
+    }
+}
+
+void file_history_add_line(file_history_t fh, const char *line)
+{
+    wrbuf_puts(fh->wr, line);
+    wrbuf_puts(fh->wr, "\n");
+}
+
+int file_history_load(file_history_t fh)
+{
+    FILE *f;
+    char* homedir = getenv("HOME");
+    char fname[1024];
+    int ret = 0;
+
+    wrbuf_rewind(fh->wr);
+    sprintf(fname, "%.500s%s%s", homedir ? homedir : "",
+            homedir ? "/" : "", ".yazclient.history");
+
+    f = fopen(fname, "r");
+    if (f)
+    {
+        int c;
+        while ((c = fgetc(f)) != EOF)
+            wrbuf_putc(fh->wr, c);
+        fclose(f);
+    }
+    return ret;
+}
+
+int file_history_save(file_history_t fh)
+{
+    FILE *f;
+    char* homedir = getenv("HOME");
+    char fname[1024];
+    int ret = 0;
+
+    sprintf(fname, "%.500s%s%s", homedir ? homedir : "",
+            homedir ? "/" : "", ".yazclient.history");
+
+    f = fopen(fname, "w");
+    if (!f)
+    {
+        ret = -1;
+    }
+    else
+    {
+        size_t w = fwrite(wrbuf_buf(fh->wr), 1, wrbuf_len(fh->wr), f);
+        if (w != wrbuf_len(fh->wr))
+            ret = -1;
+        if (fclose(f))
+            ret = -1;
+    }
+    return ret;
+}
+
+int file_history_trav(file_history_t fh, void *client_data,
+                      void (*callback)(void *client_data, const char *line))
+{
+    int off = 0;
+
+    while (off < wrbuf_len(fh->wr))
+    {
+        int i;
+        for (i = off; i < wrbuf_len(fh->wr); i++)
+        {
+            if (wrbuf_buf(fh->wr)[i] == '\n')
+            {
+                wrbuf_buf(fh->wr)[i] = '\0';
+                callback(client_data, wrbuf_buf(fh->wr) + off);
+                wrbuf_buf(fh->wr)[i] = '\n';
+                i++;
+                break;
+            }
+        }
+        off = i;
+    }
+    return 0;
+}
+
+/*
+ * Local variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ * vim: shiftwidth=4 tabstop=8 expandtab
+ */
+
diff --git a/client/fhistory.h b/client/fhistory.h
new file mode 100644 (file)
index 0000000..39777ea
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 1995-2007, Index Data ApS
+ * See the file LICENSE for details.
+ *
+ * $Id: fhistory.h,v 1.1 2007-01-24 11:50:18 adam Exp $
+ */
+/** \file fhistory.h
+ *  \brief file history header
+ */
+
+
+#ifndef YAZ_FHISTORY_H
+#define YAZ_FHISTORY_H
+
+#include <yaz/wrbuf.h>
+
+YAZ_BEGIN_CDECL
+
+typedef struct file_history *file_history_t;
+
+file_history_t file_history_new(void);
+void file_history_destroy(file_history_t *fhp);
+void file_history_add_line(file_history_t fh, const char *line);
+int file_history_save(file_history_t fh);
+int file_history_load(file_history_t fh);
+int file_history_trav(file_history_t fh, void *client_data,
+                      void (*callback)(void *client_data, const char *line));
+
+YAZ_END_CDECL
+
+#endif
+/*
+ * Local variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ * vim: shiftwidth=4 tabstop=8 expandtab
+ */
+
index 4e928ed..100dcf5 100644 (file)
@@ -8,7 +8,7 @@
      <!ENTITY % common SYSTEM "common/common.ent">
      %common;
 ]>
-<!-- $Id: yaz-client-man.xml,v 1.12 2006-08-28 19:18:02 adam Exp $ -->
+<!-- $Id: yaz-client-man.xml,v 1.13 2007-01-24 11:50:18 adam Exp $ -->
 <refentry id="yaz-client">
  <refentryinfo>
   <productname>YAZ</productname>
     <filename>yaz-&lt;version&gt;/client/client.c</filename>
    </para>
    <para>
-    <filename>.yazclientrc</filename>
+    <filename>$HOME/.yazclientrc</filename>
    </para>
    <para>
-    <filename>$HOME/.yazclientrc</filename>
+    <filename>$HOME/.yazclient.history</filename>
    </para>
   </refsect1>
   <refsect1><title>SEE ALSO</title>
index ba812f1..cda5048 100644 (file)
@@ -1,6 +1,6 @@
 # Copyright (C) 1995-2007, Index Data ApS
 # All rights reserved.
-# $Id: makefile,v 1.127 2007-01-11 10:55:57 adam Exp $
+# $Id: makefile,v 1.128 2007-01-24 11:50:19 adam Exp $
 #
 # Programmed by
 #  Heikki Levanto & Adam Dickmeiss
@@ -281,7 +281,8 @@ LINK_DLL = $(LINK) $(LNKOPT) \
 YAZ_CLIENT_OBJS= \
    $(OBJDIR)\client.obj \
    $(OBJDIR)\tabcomplete.obj \
-   $(OBJDIR)\admin.obj
+   $(OBJDIR)\admin.obj \
+   $(OBJDIR)\fhistory.obj
 
 ZTEST_OBJS= \
     $(OBJDIR)\read-marc.obj \