From: Neal H. W. <ne...@gn...> - 2004-11-20 23:33:19
|
I need the ability to automatically save the history to a file on exit from gnuplot and restore it when it is run using gnuplot's version of readline. As I am using Debian, I started my hack using that. Since it was rather simple, I have cleaned it up so that others can use it. The supplied patch is against the Debian supplied version of gnuplot (version 4.0 patch level 0). This does not cleanly apply to CVS head, however, if there is interest, I can clean it up. I have tested the patch on Debian GNU/Linux as well as on Solaris (uname -a => SunOS escher 5.8 Generic_108528-29 sun4u sparc SUNW,Ultra-60). The code should be portable to other POSIX-like environments; I don't know much about the issues porting to other systems. The patch includes three new files (src/getline.c, src/read_history.c and src/tilde_expand.c) which emulate the funtionality provided by GNU libreadline. I have licensed these under a similar license as gnuplot but (hopefully) removed the clauses which make them GPL incompatible while remaining compatible with gnuplot. If this is a problem, I am willing to discuss this. Do you need a copyright assignments? Thanks, Neal 2004-11-20 Neal H. Walfield <ne...@gn...> Add the ability to save and restore the history with gnuplot's readline implementation. * configure.in (history-file): Update comment to reflex that GNU Readline is no longer required. (GNUPLOT_HISTORY): No longer depend on the availability of <readline/tilde.h>. Check for getline, tilde_expand and read_history replacing them if they are missing. * src/Makefile.am (gnuplot_SOURCES): Add getline.c, tilde_expand.c and read_history.c. * src/getline.c: New file. * src/tilde_expand.c: New file. * src/read_history.c: New file. * src/gp_hist.h (write_history_n): Return an int, not a void. (write_history): Likewise. (read_history): Add prototype. * src/history.c: Include <string.h>. (write_history_n): Change return type from void to int. Return 0 on success to be consistent with libreadline's interface. (write_history): Likewise. * src/plot.c (expanded_history_filename) [GNUPLOT_HISTORY]: Declare even if HAVE_LIBREADLINE is not defined. (wrapper_for_write_history): Likewise. (rl_complete_with_tilde_expansion): Likewise. [GNUPLOT_HISTORY_FILE]: Likewise. (gnuplot_history_size): Likewise. (tilde_expand) [GNUPLOT_HISTORY && !HAVE_LIBREADLINE]: Declare. (main) [GNUPLOT_HISTORY]: Read and write history file (even if HAVE_LIBREADLINE is not defined). (wrapper_for_write_history) [GNUPLOT_HISTORY && !HAVE_LIBREADLINE]: Implement this case. * src/set.c (set_history_size) [GNUPLOT_HISTORY]: Declare even if HAVE_LIBREADLINE is not defined. (set_command) [GNUPLOT_HISTORY]: Recognize S_HISTORYSIZE even if HAVE_LIBREADLINE is not defined. (set_historysize) [GNUPLOT_HISTORY]: Define even if HAVE_LIBREADLINE is not defined. * src/set.c (show_history_size) [GNUPLOT_HISTORY]: Declare even if HAVE_LIBREADLINE is not defined. (show_command) [GNUPLOT_HISTORY]: Recognize S_HISTORYSIZE even if HAVE_LIBREADLINE is not defined. (show_historysize) [GNUPLOT_HISTORY]: Define even if HAVE_LIBREADLINE is not defined. * src/tables.c (set_tbl): Add S_HISTORYSIZE even if HAVE_LIBREADLINE is not defined. * src/unset.c (unset_history_size) [GNUPLOT_HISTORY]: Declare even if HAVE_LIBREADLINE is not defined. (unset_command) [GNUPLOT_HISTORY]: Recognize S_HISTORYSIZE even if HAVE_LIBREADLINE is not defined. (unset_historysize) [GNUPLOT_HISTORY]: Define even if HAVE_LIBREADLINE is not defined. * docs/gnuplot.texi (Command-line-editing): Add that the history will be saved. (historysize): This is now used if history support is enabled. diff -upr gnuplot-4.0.0-orig/configure.in gnuplot-4.0.0/configure.in --- gnuplot-4.0.0-orig/configure.in 2004-04-10 16:55:14.000000000 +0100 +++ gnuplot-4.0.0/configure.in 2004-11-20 22:00:53.000000000 +0000 @@ -261,9 +261,9 @@ AC_ARG_WITH(readline,dnl --with-readline=DIR Specify the location of GNU readline],, test -z "$with_readline" && with_readline=yes) -dnl Gnuplot history, needs GNU readline +dnl Gnuplot history AC_ARG_ENABLE(history-file,dnl -[ --enable-history-file use history file (requires GNU readline)],, +[ --enable-history-file use history file],, test -z "$enable_history_file" && enable_history_file=no) dnl GNU readline and the required terminal library @@ -310,14 +310,7 @@ please add path to readline.h to CPPFLAG AC_MSG_WARN([found GNU readline library but not history.h please add path to history.h to CPPFLAGS in Makefile])) - if test "$enable_history_file" = yes; then - AC_CHECK_HEADERS(readline/tilde.h, - AC_DEFINE(GNUPLOT_HISTORY,1, - [ Define if you want to use a gnuplot history file with GNU readline. ])) - fi - fi # ! ac_cv_lib_readline_readline = no - fi # ! with_readline != yes if test "$with_readline" = yes; then @@ -325,6 +318,17 @@ please add path to history.h to CPPFLAGS [ Define if you want to use the included readline function. ]) fi + if test "$enable_history_file" = yes; then + AC_DEFINE(GNUPLOT_HISTORY,1, + [ Define if you want to use a gnuplot history file (requires readline facilities). ]) + + AC_CHECK_HEADERS([readline/tilde.h]) + + # Check for GNU getline and libreadline's tilde_expand and read_history + # otherwise use our own replacements. + AC_REPLACE_FUNCS([getline tilde_expand read_history]) + fi + fi dnl end readline diff -upr gnuplot-4.0.0-orig/docs/gnuplot.texi gnuplot-4.0.0/docs/gnuplot.texi --- gnuplot-4.0.0-orig/docs/gnuplot.texi 2004-11-20 22:11:06.000000000 +0000 +++ gnuplot-4.0.0/docs/gnuplot.texi 2004-11-20 22:09:05.000000000 +0000 @@ -697,6 +697,10 @@ The Atari version of readline defines so @end example +When readline support is enabled, the history will be saved to the +file ~/.gnuplot_history and reloaded on start-up. This location may +be overridden by setting the GNUPLOT_HISTORY_FILE environment +variable. @node Comments, Coordinates, Command-line-editing, gnuplot @section Comments @@ -6627,7 +6631,7 @@ and @cindex nohistorysize Note: the command @ref{historysize} is only available when -compiled with the gnu readline. +compiled with readline support. Syntax: @example diff -upr gnuplot-4.0.0-orig/src/Makefile.am gnuplot-4.0.0/src/Makefile.am --- gnuplot-4.0.0-orig/src/Makefile.am 2004-02-19 22:43:14.000000000 +0000 +++ gnuplot-4.0.0/src/Makefile.am 2004-11-20 20:56:21.000000000 +0000 @@ -24,19 +24,20 @@ noinst_PROGRAMS = bf_test XLIBS = @LIBRARIES_FOR_X@ AM_CPPFLAGS = -I../term -I$(top_srcdir)/term -DBINDIR=\"$(bindir)\" -DX11_DRIVER_DIR=\"$(X11_DRIVER_DIR)\" -DCONTACT=\"$(EMAIL)\" -DHELPFILE=\"$(HELPFILE)\" -gnuplot_SOURCES = alloc.c alloc.h ansichek.h axis.c axis.h binary.c \ -binary.h bitmap.c bitmap.h color.c color.h command.c command.h \ -contour.c contour.h datafile.c datafile.h dynarray.c dynarray.h eval.c \ -eval.h fit.c fit.h gadgets.c gadgets.h getcolor.c getcolor.h \ -gp_hist.h gp_time.h gp_types.h graph3d.c graph3d.h graphics.c graphics.h \ -help.c help.h hidden3d.c hidden3d.h history.c internal.c internal.h \ -interpol.c interpol.h matrix.c matrix.h misc.c misc.h mouse.c mouse.h \ -mousecmn.h national.h parse.c parse.h plot.c plot.h plot2d.c plot2d.h \ -plot3d.c plot3d.h pm3d.c pm3d.h readline.c readline.h save.c \ -save.h scanner.c scanner.h set.c setshow.h show.c specfun.c specfun.h \ -standard.c standard.h stdfn.c stdfn.h syscfg.h tables.c tables.h \ -template.h term_api.h term.c term.h time.c unset.c util.c util.h \ -util3d.c util3d.h variable.c variable.h version.c version.h +gnuplot_SOURCES = alloc.c alloc.h ansichek.h axis.c axis.h binary.c \ +binary.h bitmap.c bitmap.h color.c color.h command.c command.h \ +contour.c contour.h datafile.c datafile.h dynarray.c dynarray.h eval.c \ +eval.h fit.c fit.h gadgets.c gadgets.h getcolor.c getcolor.h getline.c \ +gp_hist.h gp_time.h gp_types.h graph3d.c graph3d.h graphics.c \ +graphics.h help.c help.h hidden3d.c hidden3d.h history.c internal.c \ +internal.h interpol.c interpol.h matrix.c matrix.h misc.c misc.h \ +mouse.c mouse.h mousecmn.h national.h parse.c parse.h plot.c plot.h \ +plot2d.c plot2d.h plot3d.c plot3d.h pm3d.c pm3d.h read_history.c \ +readline.c readline.h save.c save.h scanner.c scanner.h set.c \ +setshow.h show.c specfun.c specfun.h standard.c standard.h stdfn.c \ +stdfn.h syscfg.h tables.c tables.h template.h term_api.h term.c term.h \ +tilde_expand.c time.c unset.c util.c util.h util3d.c util3d.h \ +variable.c variable.h version.c version.h gnuplot_LDADD = $(TERMLIBS) $(TERMXLIBS) diff -upr gnuplot-4.0.0-orig/src/gp_hist.h gnuplot-4.0.0/src/gp_hist.h --- gnuplot-4.0.0-orig/src/gp_hist.h 2004-04-13 18:23:53.000000000 +0100 +++ gnuplot-4.0.0/src/gp_hist.h 2004-11-20 12:15:24.000000000 +0000 @@ -64,10 +64,11 @@ extern struct hist *cur_entry; #if defined(READLINE) && !defined(HAVE_LIBREADLINE) void add_history __PROTO((char *line)); -void write_history_n __PROTO((const int, const char *, const char *)); -void write_history __PROTO((char *)); +int write_history_n __PROTO((const int, const char *, const char *)); +int write_history __PROTO((char *)); char *history_find __PROTO((char *)); int history_find_all __PROTO((char *)); +void read_history __PROTO((const char *)); #endif /* READLINE && !HAVE_LIBREADLINE */ #endif /* GNUPLOT_HISTORY_H */ diff -upr gnuplot-4.0.0-orig/src/history.c gnuplot-4.0.0/src/history.c --- gnuplot-4.0.0-orig/src/history.c 2004-04-13 18:23:58.000000000 +0100 +++ gnuplot-4.0.0/src/history.c 2004-11-20 21:04:13.000000000 +0000 @@ -35,6 +35,7 @@ static char *RCSid() { return RCSid("$Id ]*/ #include <stdio.h> +#include <string.h> #include "gp_hist.h" @@ -117,8 +118,10 @@ char *line; * filename == "" ... write to stdout, but without entry numbers * mode ... should be "w" or "a" to select write or append for file, * ignored if history is written to a pipe + * Return value: + * 0 on success. */ -void +int write_history_n(n, filename, mode) const int n; const char *filename; @@ -131,7 +134,7 @@ const char *mode; int hist_index = 1; if (entry == NULL) - return; /* no history yet */ + return 0; /* no history yet */ /* find the beginning of the history and count nb of entries */ while (entry->prev != NULL) { @@ -172,19 +175,23 @@ const char *mode; pclose(out); else #endif - fclose(out); -} + fclose(out); + } + + return 0; } /* obviously the same routine as in GNU readline, according to code from - * plot.c:#if defined(HAVE_LIBREADLINE) && defined(GNUPLOT_HISTORY) + * plot.c:#if defined(GNUPLOT_HISTORY) + * Return value: + * 0 on success. */ -void +int write_history(filename) char *filename; { - write_history_n(0, filename, "w"); + return write_history_n(0, filename, "w"); } diff -upr gnuplot-4.0.0-orig/src/plot.c gnuplot-4.0.0/src/plot.c --- gnuplot-4.0.0-orig/src/plot.c 2004-04-14 16:26:21.000000000 +0100 +++ gnuplot-4.0.0/src/plot.c 2004-11-20 12:48:08.000000000 +0000 @@ -99,24 +99,7 @@ extern smg$create_key_table(); # endif #endif /* _Windows */ -/* GNU readline - * Only required by two files directly, - * so I don't put this into a header file. -lh - */ -#ifdef HAVE_LIBREADLINE -extern int rl_complete_with_tilde_expansion; - -/* enable gnuplot history with readline */ -# ifdef GNUPLOT_HISTORY -# include <readline/tilde.h> -# ifndef GNUPLOT_HISTORY_FILE -# define GNUPLOT_HISTORY_FILE "~/.gnuplot_history" -# endif -# ifndef HISTORY_SIZE -/* Can be overriden with the environment variable 'GNUPLOT_HISTORY_SIZE' */ -# define HISTORY_SIZE 666 -# endif -long int gnuplot_history_size = HISTORY_SIZE; +#if defined(GNUPLOT_HISTORY) /* * The next variable is a pointer to the value returned from 'tilde_expand()'. * This function expands '~' to the user's home directory, or $HOME, with @@ -128,8 +111,29 @@ static char *expanded_history_filename; static void wrapper_for_write_history __PROTO((void)); -# endif /* GNUPLOT_HISTORY */ -#endif /* HAVE_LIBREADLINE */ +extern int rl_complete_with_tilde_expansion; + +/* GNU readline + * Only required by two files directly, + * so I don't put this into a header file. -lh + */ +/* enable gnuplot history with readline */ +# ifdef HAVE_LIBREADLINE +# include <readline/tilde.h> +# else +extern char *tilde_expand(const char *path); +# endif + +# ifndef GNUPLOT_HISTORY_FILE +# define GNUPLOT_HISTORY_FILE "~/.gnuplot_history" +# endif +# ifndef HISTORY_SIZE +/* Can be overriden with the environment variable 'GNUPLOT_HISTORY_SIZE' */ +# define HISTORY_SIZE 666 +# endif +long int gnuplot_history_size = HISTORY_SIZE; + +#endif /* GNUPLOT_HISTORY */ TBOOLEAN interactive = TRUE; /* FALSE if stdin not a terminal */ static TBOOLEAN noinputfiles = TRUE; /* FALSE if there are script files */ @@ -531,10 +535,13 @@ main(argc, argv) init_fit(); /* Initialization of fitting module */ if (interactive && term != 0) { /* not unknown */ -#if defined(HAVE_LIBREADLINE) && defined(GNUPLOT_HISTORY) +#if defined(GNUPLOT_HISTORY) FPRINTF((stderr, "Before read_history\n")); - expanded_history_filename = tilde_expand(GNUPLOT_HISTORY_FILE); - FPRINTF((stderr, "expanded_history_filename = %s\n", expanded_history_filename)); + expanded_history_filename + = tilde_expand(getenv ("GNUPLOT_HISTORY_FILE") + ?: GNUPLOT_HISTORY_FILE); + FPRINTF((stderr, "expanded_history_filename = %s\n", + expanded_history_filename)); read_history(expanded_history_filename); { /* BEGIN: Go local to get environment variable */ @@ -553,7 +560,7 @@ main(argc, argv) * want to use them, 'write_history()' is called directly. */ GP_ATEXIT(wrapper_for_write_history); -#endif /* HAVE_LIBREADLINE && GNUPLOT_HISTORY */ +#endif /* GNUPLOT_HISTORY */ fprintf(stderr, "\nTerminal type set to '%s'\n", term->name); } /* if (interactive && term != 0) */ @@ -632,12 +641,12 @@ main(argc, argv) while (!com_line()); } -#if defined(HAVE_LIBREADLINE) && defined(GNUPLOT_HISTORY) +#if defined(GNUPLOT_HISTORY) #if !defined(HAVE_ATEXIT) && !defined(HAVE_ON_EXIT) /* You should be here if you neither have 'atexit()' nor 'on_exit()' */ wrapper_for_write_history(); #endif /* !HAVE_ATEXIT && !HAVE_ON_EXIT */ -#endif /* HAVE_LIBREADLINE && GNUPLOT_HISTORY */ +#endif /* GNUPLOT_HISTORY */ term_reset(); @@ -923,11 +932,12 @@ RexxInterface(PRXSTRING rxCmd, PUSHORT p } #endif -#if defined(HAVE_LIBREADLINE) && defined(GNUPLOT_HISTORY) +#if defined(GNUPLOT_HISTORY) static void wrapper_for_write_history() { -#if 1 +#if defined(HAVE_LIBREADLINE) +# if 1 /* Alternative code, saves one disk access */ if (history_is_stifled()) unstifle_history(); @@ -939,14 +949,20 @@ wrapper_for_write_history() fprintf (stderr, "Warning: Could not write history file!!!\n"); unstifle_history(); -#else +# else /* if writing was successful, truncate history * to gnuplot_history_size lines */ if (write_history(expanded_history_filename)) { +# if defined(HAVE_LIBREADLINE) if (gnuplot_history_size >= 0) history_truncate_file(expanded_history_filename, gnuplot_history_size); +# endif } +# endif + +#else /* HAVE_LIBREADLINE */ + write_history_n(gnuplot_history_size, expanded_history_filename, "w"); #endif } -#endif /* HAVE_LIBREADLINE && GNUPLOT_HISTORY */ +#endif /* GNUPLOT_HISTORY */ diff -upr gnuplot-4.0.0-orig/src/set.c gnuplot-4.0.0/src/set.c --- gnuplot-4.0.0-orig/src/set.c 2004-04-13 18:24:00.000000000 +0100 +++ gnuplot-4.0.0/src/set.c 2004-11-19 16:46:04.000000000 +0000 @@ -91,7 +91,7 @@ static void set_fit __PROTO((void)); static void set_format __PROTO((void)); static void set_grid __PROTO((void)); static void set_hidden3d __PROTO((void)); -#if defined(HAVE_LIBREADLINE) && defined(GNUPLOT_HISTORY) +#if defined(GNUPLOT_HISTORY) static void set_historysize __PROTO((void)); #endif static void set_isosamples __PROTO((void)); @@ -301,7 +301,7 @@ set_command() case S_HIDDEN3D: set_hidden3d(); break; -#if defined(HAVE_LIBREADLINE) && defined(GNUPLOT_HISTORY) +#if defined(GNUPLOT_HISTORY) case S_HISTORYSIZE: set_historysize(); break; @@ -1404,7 +1404,7 @@ set_hidden3d() } -#if defined(HAVE_LIBREADLINE) && defined(GNUPLOT_HISTORY) +#if defined(GNUPLOT_HISTORY) /* process 'set historysize' command */ static void set_historysize() Only in gnuplot-4.0.0/src: set.o diff -upr gnuplot-4.0.0-orig/src/show.c gnuplot-4.0.0/src/show.c --- gnuplot-4.0.0-orig/src/show.c 2004-04-15 11:02:11.000000000 +0100 +++ gnuplot-4.0.0/src/show.c 2004-11-19 16:46:35.000000000 +0000 @@ -128,7 +128,7 @@ static void show_isosamples __PROTO((voi static void show_view __PROTO((void)); static void show_surface __PROTO((void)); static void show_hidden3d __PROTO((void)); -#if defined(HAVE_LIBREADLINE) && defined(GNUPLOT_HISTORY) +#if defined(GNUPLOT_HISTORY) static void show_historysize __PROTO((void)); #endif static void show_size __PROTO((void)); @@ -384,7 +384,7 @@ show_command() case S_HIDDEN3D: show_hidden3d(); break; -#if defined(HAVE_LIBREADLINE) && defined(GNUPLOT_HISTORY) +#if defined(GNUPLOT_HISTORY) case S_HISTORYSIZE: show_historysize(); break; @@ -790,7 +790,7 @@ show_all() show_view(); show_surface(); show_hidden3d(); -#if defined(HAVE_LIBREADLINE) && defined(GNUPLOT_HISTORY) +#if defined(GNUPLOT_HISTORY) show_historysize(); #endif show_size(); @@ -2381,7 +2381,7 @@ show_hidden3d() } -#if defined(HAVE_LIBREADLINE) && defined(GNUPLOT_HISTORY) +#if defined(GNUPLOT_HISTORY) /* process 'show historysize' command */ static void show_historysize() diff -upr gnuplot-4.0.0-orig/src/tables.c gnuplot-4.0.0/src/tables.c --- gnuplot-4.0.0-orig/src/tables.c 2004-04-13 18:24:01.000000000 +0100 +++ gnuplot-4.0.0/src/tables.c 2004-11-19 16:46:44.000000000 +0000 @@ -178,7 +178,7 @@ const struct gen_table set_tbl[] = { "fu$nctions", S_FUNCTIONS }, { "g$rid", S_GRID }, { "hid$den3d", S_HIDDEN3D }, -#if defined(HAVE_LIBREADLINE) && defined(GNUPLOT_HISTORY) +#if defined(GNUPLOT_HISTORY) { "his$torysize", S_HISTORYSIZE }, #endif { "is$osamples", S_ISOSAMPLES }, diff -upr gnuplot-4.0.0-orig/src/unset.c gnuplot-4.0.0/src/unset.c --- gnuplot-4.0.0-orig/src/unset.c 2004-04-13 18:24:02.000000000 +0100 +++ gnuplot-4.0.0/src/unset.c 2004-11-19 16:47:07.000000000 +0000 @@ -83,7 +83,7 @@ static void unset_fit __PROTO((void)); static void unset_format __PROTO((void)); static void unset_grid __PROTO((void)); static void unset_hidden3d __PROTO((void)); -#if defined(HAVE_LIBREADLINE) && defined(GNUPLOT_HISTORY) +#if defined(GNUPLOT_HISTORY) static void unset_historysize __PROTO((void)); #endif static void unset_isosamples __PROTO((void)); @@ -224,7 +224,7 @@ unset_command() case S_HIDDEN3D: unset_hidden3d(); break; -#if defined(HAVE_LIBREADLINE) && defined(GNUPLOT_HISTORY) +#if defined(GNUPLOT_HISTORY) case S_HISTORYSIZE: unset_historysize(); break; @@ -813,7 +813,7 @@ unset_hidden3d() } -#if defined(HAVE_LIBREADLINE) && defined(GNUPLOT_HISTORY) +#if defined(GNUPLOT_HISTORY) /* process 'unset historysize' command */ static void unset_historysize() --- /dev/null 2004-10-30 17:33:07.000000000 +0100 +++ gnuplot-4.0.0/src/getline.c 2004-11-20 22:00:19.000000000 +0000 @@ -0,0 +1,101 @@ +/*[ + * Copyright 2004 Neal H. Walfield + * + * Permission to use, copy, and distribute this software and its + * documentation for any purpose with or without fee is hereby + * granted, provided that this permission notice appear in supporting + * documentation. + * + * Permission to modify the software is granted. Permission to + * distribute binaries produced by compiling modified sources is granted, + * provided you + * 1. distribute the corresponding source modifications + * 2. retain our contact information in regard to use of the base + * software. + * Permission to distribute the released version of the source code is + * granted with same provision 2 for binary distributions. + * + * This software is provided "as is" without express or implied warranty + * to the extent permitted by applicable law. + ]*/ + +#include "config.h" + +/* Only needed if compiling with readline support. */ +#ifdef READLINE + +# ifndef HAVE_GETLINE + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> /* For ssize_t. */ + +#define INITAL_ALLOC 128 + +/* Append character C to the buffer *LINE of size *S filled with *LEN + bytes so far. Increase the buffer if necessary using realloc. + Returns -1 on failure. */ +static int +add_char (char **line, size_t *s, ssize_t *len, int c) +{ + if (*len == *s) { + char *temp; + + if (*s == 0) { + temp = malloc (INITAL_ALLOC); + if (! temp) + return -1; + + *line = temp; + *s = INITAL_ALLOC; + } else { + temp = realloc (*line, *s * 2); + if (! temp) + return -1; + + *line = temp; + *s *= 2; + } + } + + (*line)[(*len) ++] = c; + return 0; +} + +/* Replacement for GNU getline. */ +ssize_t +getline (char **line, size_t *s, FILE *fp) +{ + int err; + ssize_t len = 0; + int c; + + do { + c = fgetc (fp); + if (c == EOF) { + if (len == 0) + /* Got an EOF and have not read any characters. */ + return -1; + else + break; + } + + err = add_char (line, s, &len, c); + if (err == -1) + return err; + } while ((*line)[len - 1] != '\n'); + + /* Add the NUL terminator. */ + err = add_char (line, s, &len, '\0'); + if (err == -1) + return err; + + /* Success. Return the number of bytes read from the file (which, + of course, does not include the NUL terminator which we just + added. */ + return len - 1; +} + +# endif /* HAVE_GET_LINE */ + +#endif /* READLINE */ --- /dev/null 2004-10-30 17:33:07.000000000 +0100 +++ gnuplot-4.0.0/src/read_history.c 2004-11-20 21:02:29.000000000 +0000 @@ -0,0 +1,74 @@ +/*[ + * Copyright 2004 Neal H. Walfield + * + * Permission to use, copy, and distribute this software and its + * documentation for any purpose with or without fee is hereby + * granted, provided that this permission notice appear in supporting + * documentation. + * + * Permission to modify the software is granted. Permission to + * distribute binaries produced by compiling modified sources is granted, + * provided you + * 1. distribute the corresponding source modifications + * 2. retain our contact information in regard to use of the base + * software. + * Permission to distribute the released version of the source code is + * granted with same provision 2 for binary distributions. + * + * This software is provided "as is" without express or implied warranty + * to the extent permitted by applicable law. + ]*/ + +#include "config.h" + +/* Only needed if compiling with readline support. */ +#ifdef READLINE + +# ifndef HAVE_READ_HISTORY + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> + +/* Replacement for readline's read_history. */ +void +read_history(const char *filename) +{ + FILE *fp; + char *line; + int line_len; + + fp = fopen (filename, "r"); + if (! fp) { + fprintf (stderr, "Unable to read history file %s: %s.", filename, + strerror (errno)); + return; + } + + line = 0; + line_len = 0; + + /* Slurp the history file. If any of the lines contain NULL + characters then anything after that won't be added to the + history but it won't hurt us either. */ + while (getline (&line, &line_len, fp) != -1) { + /* Kill the trailing newline (if any). */ + while (strlen (line) > 0 + && (line[strlen (line) - 1] == '\n' + || line[strlen (line) - 1] == '\r')) + line[strlen (line) - 1] = '\0'; + + if (strlen (line) > 0) + add_history (line); + } + + if (line) + free (line); + + fclose (fp); +} + +# endif /* HAVE_READ_HISTORY */ + +#endif /* READLINE */ --- /dev/null 2004-10-30 17:33:07.000000000 +0100 +++ gnuplot-4.0.0/src/tilde_expand.c 2004-11-20 21:04:26.000000000 +0000 @@ -0,0 +1,104 @@ +/*[ + * Copyright 2004 Neal H. Walfield + * + * Permission to use, copy, and distribute this software and its + * documentation for any purpose with or without fee is hereby + * granted, provided that this permission notice appear in supporting + * documentation. + * + * Permission to modify the software is granted. Permission to + * distribute binaries produced by compiling modified sources is granted, + * provided you + * 1. distribute the corresponding source modifications + * 2. retain our contact information in regard to use of the base + * software. + * Permission to distribute the released version of the source code is + * granted with same provision 2 for binary distributions. + * + * This software is provided "as is" without express or implied warranty + * to the extent permitted by applicable law. + ]*/ + +#include "config.h" + +/* Only needed if compiling with readline support. */ +#ifdef READLINE + +# ifndef HAVE_TILDE_EXPAND + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <pwd.h> + +/* Replacement for readline's tilde_expand. */ +char * +tilde_expand(const char *path) +{ + if (*path != '~') + /* Does not start with a ~. */ + return strdup (path); + + if (strcmp ("~", path) == 0) + /* Is exactly "~". */ + return strdup (getenv ("HOME")); + + if (strncmp ("~/", path, 2) == 0) { + /* Starts with ~/. */ + + const char *home = getenv ("HOME"); + char *p; + + if (! home) + return strdup (path); + + p = malloc (strlen (home) + 1 + strlen (path) - 2 + 1); + if (! p) { + fprintf (stderr, "malloc failed."); + abort (); + } + + memcpy (p, home, strlen (home)); + memcpy (p + strlen (home), path + 1, strlen (path + 1) + 1); + + return p; + } + + { + /* Must be "~user" or "~user/...". */ + + char *rest = strchr (path, '/'); + int user_len = rest ? rest - (path + 1) : strlen (path + 1); + + struct passwd *pwd; + char *p; + + setpwent (); + + while ((pwd = getpwent ())) { + if (strncmp (path + 1, pwd->pw_name, user_len) == 0) { + p = malloc (strlen (pwd->pw_dir) + 1 + strlen (path) - 2 + 1); + if (! p) { + fprintf (stderr, "malloc failed."); + abort (); + } + + memcpy (p, pwd->pw_dir, strlen (pwd->pw_dir)); + strcpy (p + strlen (pwd->pw_dir), path + 1 + user_len); + + return p; + } + } + + endpwent (); + + if (! pwd) + /* Did not find the user. */ + p = strdup (path); + + return p; + } +} + +# endif /* HAVE_TILDE_EXPAND */ +#endif /* READLINE */ |