Added readline patch (support for command history).
This commit is contained in:
parent
8d05f51d74
commit
8686a73047
18
ChangeLog
18
ChangeLog
|
|
@ -1,3 +1,21 @@
|
|||
2003-08-14 Paolo Nenzi <p.nenzi@ieee.org>
|
||||
|
||||
* configure.in, src/main.c, src/misc/tilde.c, src/misc/tilde.h,
|
||||
src/frontend/com_history.c, src/frontend/misccoms.h,
|
||||
src/frontend/signal_handler.c, src/frontend/plotting/x11.c,
|
||||
src/frontend/parser/glob.c, src/include/ngspice.h:
|
||||
|
||||
Added Andrew Veliath patch fo readline support. Using
|
||||
readline with ngspice IS A VIOLATION OF GPL LICENSE, you
|
||||
have been warned. The final decision is up to you. The
|
||||
patch has been applied in the perspective of changing
|
||||
readline library with libedit. Libedit aims to be a
|
||||
replacement of readline and is covered by BSD license.
|
||||
Libedit is available at the URL: libedit.sourceforge.net.
|
||||
|
||||
Readline code has been extrapolated from a patch available
|
||||
on http://www.btae.mam.gov.tr/~genc/ngspice/.
|
||||
|
||||
2003-08-11 Paolo Nenzi <p.nenzi@ieee.org>
|
||||
|
||||
* doc/ngspice.texi: updated documentation. Still incomplete
|
||||
|
|
|
|||
|
|
@ -463,9 +463,8 @@ fi
|
|||
|
||||
dnl --with-readline : the user wants to use readline library
|
||||
AC_ARG_WITH(readline,
|
||||
[ --with-readline Use the readline package: SEE README],
|
||||
[ --with-readline Use the readline library. WARNING: breaks GPL license],
|
||||
AC_MSG_RESULT(Checking for readline library:)
|
||||
Check for the readline library:
|
||||
AC_CHECK_LIB(readline, readline, AC_DEFINE(HAVE_GNUREADLINE) LIBS="$LIBS -lreadline")
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -10,6 +10,13 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
|
|||
|
||||
#include "com_history.h"
|
||||
|
||||
#ifdef HAVE_GNUREADLINE
|
||||
|
||||
/* Added GNU Readline Support -- Andrew Veliath <veliaa@rpi.edu> */
|
||||
#include <readline/readline.h>
|
||||
#include <readline/history.h>
|
||||
|
||||
#endif /* HAVE_GNUREADLINE */
|
||||
|
||||
/* static declarations */
|
||||
static wordlist * dohsubst(char *string);
|
||||
|
|
@ -346,8 +353,10 @@ cp_addhistent(int event, wordlist *wlist)
|
|||
cp_lastone->hi_next = NULL;
|
||||
cp_lastone->hi_event = event;
|
||||
cp_lastone->hi_wlist = wl_copy(wlist);
|
||||
#ifndef HAVE_GNUREADLINE
|
||||
freehist(histlength - cp_maxhistlength);
|
||||
histlength++;
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -484,10 +493,36 @@ com_history(wordlist *wl)
|
|||
wl = wl->wl_next;
|
||||
rev = TRUE;
|
||||
}
|
||||
#ifdef HAVE_GNUREADLINE
|
||||
/* Added GNU Readline Support -- Andrew Veliath <veliaa@rpi.edu> */
|
||||
{
|
||||
HIST_ENTRY *he;
|
||||
int i, N;
|
||||
|
||||
N = (wl == NULL) ? history_length : atoi(wl->wl_word);
|
||||
|
||||
if (N < 0) N = 0;
|
||||
if (N > history_length) N = history_length;
|
||||
|
||||
if (rev)
|
||||
for (i = history_length; i > 0 && N; --i, --N) {
|
||||
he = history_get(i);
|
||||
if (!he) return;
|
||||
fprintf(cp_out, "%d\t%s\n", i, he->line);
|
||||
}
|
||||
else
|
||||
for (i = history_length - N + 1; i <= history_length; ++i) {
|
||||
he = history_get(i);
|
||||
if (!he) return;
|
||||
fprintf(cp_out, "%d\t%s\n", i, he->line);
|
||||
}
|
||||
}
|
||||
#else
|
||||
if (wl == NULL)
|
||||
cp_hprint(cp_event - 1, cp_event - histlength, rev);
|
||||
else
|
||||
cp_hprint(cp_event - 1, cp_event - 1 - atoi(wl->wl_word), rev);
|
||||
#endif /* ifelse HAVE_GNUREADLINE */
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -15,6 +15,13 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
|
|||
#include "hcomp.h"
|
||||
#include "variable.h"
|
||||
|
||||
#ifdef HAVE_GNUREADLINE
|
||||
#include <readline/readline.h>
|
||||
#include <readline/history.h>
|
||||
|
||||
extern int gnu_history_lines;
|
||||
extern char gnu_history_file[];
|
||||
#endif
|
||||
|
||||
static void byemesg(void);
|
||||
|
||||
|
|
@ -79,9 +86,14 @@ com_quit(wordlist *wl)
|
|||
byemesg();
|
||||
} else
|
||||
byemesg();
|
||||
|
||||
#ifdef HAVE_GNUREADLINE
|
||||
/* Added GNU Readline Support -- Andrew Veliath <veliaa@rpi.edu> */
|
||||
if (cp_interactive && (cp_maxhistlength > 0)) {
|
||||
stifle_history(cp_maxhistlength);
|
||||
write_history(gnu_history_file);
|
||||
}
|
||||
#endif /* HAVE_GNUREADLINE */
|
||||
exit(EXIT_NORMAL);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ char cp_til = '~';
|
|||
* globbing in them. Sort after the second phase but not the first...
|
||||
*/
|
||||
|
||||
/* MW. Now only tilde is supportef, {}*? don't work */
|
||||
/* MW. Now only tilde is supported, {}*? don't work */
|
||||
|
||||
wordlist *
|
||||
cp_doglob(wordlist *wlist)
|
||||
|
|
@ -72,8 +72,11 @@ cp_tildexpand(char *string)
|
|||
{
|
||||
char *result;
|
||||
|
||||
#ifdef HAVE_READLINE
|
||||
result = tildexpand(string);
|
||||
#else
|
||||
result = tilde_expand(string);
|
||||
|
||||
#endif
|
||||
if (!result) {
|
||||
if (cp_nonomatch) {
|
||||
return copy(string);
|
||||
|
|
|
|||
|
|
@ -788,12 +788,15 @@ zoomin(GRAPH *graph)
|
|||
graph->commandline, fx0, fx1, fy0, fy1);
|
||||
}
|
||||
|
||||
/* don't use the following if using GNU Readline - AV */
|
||||
#ifndef HAVE_GNUREADLINE
|
||||
/* hack for Gordon Jacobs */
|
||||
/* add to history list if plothistory is set */
|
||||
if (cp_getvar("plothistory", VT_BOOL, (char *) &dummy)) {
|
||||
wl = cp_parse(buf);
|
||||
(void) cp_addhistent(cp_event++, wl);
|
||||
}
|
||||
#endif /* HAVE_GNUREADLINE */
|
||||
|
||||
(void) cp_evloop(buf);
|
||||
|
||||
|
|
|
|||
|
|
@ -32,6 +32,8 @@ extern jmp_buf jbuf;
|
|||
|
||||
extern pid_t getpid (void);
|
||||
|
||||
/* not using SIGINT with GNU Readline - AV */
|
||||
#ifndef HAVE_GNUREADLINE
|
||||
RETSIGTYPE
|
||||
ft_sigintr(void)
|
||||
{
|
||||
|
|
@ -55,7 +57,7 @@ ft_sigintr(void)
|
|||
cp_resetcontrol();
|
||||
longjmp(jbuf, 1);
|
||||
}
|
||||
|
||||
#endif /* !HAVE_GNUREADLINE */
|
||||
|
||||
RETSIGTYPE
|
||||
sigfloat(int sig, int code)
|
||||
|
|
|
|||
|
|
@ -134,8 +134,11 @@ extern int scannum(char *str);
|
|||
extern int ciprefix(register char *p, register char *s);
|
||||
extern int cieq(register char *p, register char *s);
|
||||
extern void strtolower(char *str);
|
||||
#ifdef HAVE_GNUREADLINE
|
||||
extern char *tildexpand(char *string);
|
||||
#else
|
||||
extern char *tilde_expand(char *string);
|
||||
|
||||
#endif
|
||||
extern char *smktemp(char *id);
|
||||
|
||||
extern char *copy(char *str);
|
||||
|
|
|
|||
115
src/main.c
115
src/main.c
|
|
@ -43,6 +43,14 @@
|
|||
#include <pwd.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_GNUREADLINE
|
||||
/* Added GNU Readline Support 11/3/97 -- Andrew Veliath <veliaa@rpi.edu> */
|
||||
/* from spice3f4 patch to ng-spice. jmr */
|
||||
#include <readline/readline.h>
|
||||
#include <readline/history.h>
|
||||
#include "fteinput.h"
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_GETRUSAGE
|
||||
#ifdef HAVE_FTIME
|
||||
#include <sys/timeb.h>
|
||||
|
|
@ -64,6 +72,11 @@ bool ft_intrpt = FALSE; /* Set by the (void) signal handlers. */
|
|||
bool ft_setflag = FALSE; /* Don't abort after an interrupt. */
|
||||
char *ft_rawfile = "rawspice.raw";
|
||||
|
||||
#ifdef HAVE_GNUREADLINE
|
||||
char gnu_history_file[512];
|
||||
static char *application_name;
|
||||
#endif
|
||||
|
||||
bool oflag = FALSE; /* Output über redefinierte Funktionen */
|
||||
FILE *flogp; // hvogt 15.12.2001
|
||||
|
||||
|
|
@ -309,6 +322,89 @@ shutdown(int exitval)
|
|||
exit (exitval);
|
||||
}
|
||||
|
||||
#ifdef HAVE_GNUREADLINE
|
||||
/* Adapted ../lib/cp/lexical.c:prompt() for GNU Readline -- Andrew Veliath <veliaa@rpi.edu> */
|
||||
static char *
|
||||
prompt()
|
||||
{
|
||||
static char pbuf[128];
|
||||
char *p = pbuf, *s;
|
||||
|
||||
if (cp_interactive == FALSE)
|
||||
return;
|
||||
if (cp_promptstring == NULL)
|
||||
s = "-> ";
|
||||
else
|
||||
s = cp_promptstring;
|
||||
if (cp_altprompt)
|
||||
s = cp_altprompt;
|
||||
while (*s) {
|
||||
switch (strip(*s)) {
|
||||
case '!':
|
||||
p += sprintf(p, "%d", where_history() + 1);
|
||||
break;
|
||||
case '\\':
|
||||
if (*(s + 1))
|
||||
p += sprintf(p, "%c", strip(*++s));
|
||||
default:
|
||||
*p = strip(*s); ++p;
|
||||
break;
|
||||
}
|
||||
s++;
|
||||
}
|
||||
*p = 0;
|
||||
return pbuf;
|
||||
}
|
||||
|
||||
/* Process device events in Readline's hook since there is no where
|
||||
else to do it now - AV */
|
||||
int rl_event_func()
|
||||
{
|
||||
static REQUEST reqst = { checkup_option, 0 };
|
||||
Input(&reqst, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Added GNU Readline Support -- Andrew Veliath <veliaa@rpi.edu> */
|
||||
void app_rl_readlines()
|
||||
{
|
||||
char *line, *expanded_line;
|
||||
|
||||
strcpy(gnu_history_file, getenv("HOME"));
|
||||
strcat(gnu_history_file, "/.");
|
||||
strcat(gnu_history_file, application_name);
|
||||
strcat(gnu_history_file, "_history");
|
||||
|
||||
using_history();
|
||||
read_history(gnu_history_file);
|
||||
|
||||
rl_readline_name = application_name;
|
||||
rl_instream = cp_in;
|
||||
rl_outstream = cp_out;
|
||||
rl_event_hook = rl_event_func;
|
||||
|
||||
while (1) {
|
||||
history_set_pos(history_length);
|
||||
line = readline(prompt());
|
||||
if (line && *line) {
|
||||
int s = history_expand(line, &expanded_line);
|
||||
|
||||
if (s == 2) {
|
||||
fprintf(stderr, "-> %s\n", expanded_line);
|
||||
} else if (s == -1) {
|
||||
fprintf(stderr, "readline: %s\n", expanded_line);
|
||||
} else {
|
||||
cp_evloop(expanded_line);
|
||||
add_history(expanded_line);
|
||||
}
|
||||
free(expanded_line);
|
||||
}
|
||||
if (line) free(line);
|
||||
}
|
||||
/* History gets written in ../fte/misccoms.c com_quit */
|
||||
}
|
||||
#endif /* HAVE_GNUREADLINE */
|
||||
|
||||
void
|
||||
show_help(void)
|
||||
{
|
||||
|
|
@ -423,6 +519,13 @@ main(int argc, char **argv)
|
|||
}
|
||||
started = TRUE;
|
||||
|
||||
#ifdef HAVE_GNUREADLINE
|
||||
if (!(application_name = strrchr(argv[0],'/')))
|
||||
application_name = argv[0];
|
||||
else
|
||||
++application_name;
|
||||
#endif
|
||||
|
||||
#ifdef PARALLEL_ARCH
|
||||
PBEGIN_(argc, argv);
|
||||
ARCHme = NODEID_();
|
||||
|
|
@ -617,7 +720,11 @@ main(int argc, char **argv)
|
|||
|
||||
/* Set up signal handling */
|
||||
if (!ft_batchmode) {
|
||||
|
||||
#ifndef HAVE_GNUREADLINE
|
||||
signal(SIGINT, ft_sigintr);
|
||||
#endif
|
||||
|
||||
signal(SIGFPE, sigfloat);
|
||||
#if defined(SIGTSTP) // && !defined(__MINGW32__)
|
||||
signal(SIGTSTP, sigstop);
|
||||
|
|
@ -788,7 +895,11 @@ evl:
|
|||
} else {
|
||||
(void) setjmp(jbuf);
|
||||
cp_interactive = TRUE;
|
||||
#ifdef HAVE_GNUREADLINE
|
||||
app_rl_readlines();
|
||||
#else
|
||||
while (cp_evloop((char *) NULL) == 1) ;
|
||||
#endif /* ifelse HAVE_GNUREADLINE */
|
||||
}
|
||||
|
||||
#else /* ~ SIMULATOR */
|
||||
|
|
@ -806,7 +917,11 @@ evl:
|
|||
/* Nutmeg "main" */
|
||||
(void) setjmp(jbuf);
|
||||
cp_interactive = TRUE;
|
||||
#ifdef HAVE_GNUREADLINE
|
||||
app_rl_readlines();
|
||||
#else
|
||||
while (cp_evloop((char *) NULL) == 1) ;
|
||||
#endif /* ifelse HAVE_GNUREADLINE */
|
||||
|
||||
#endif /* ~ SIMULATOR */
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
/**********
|
||||
Copyright 1991 Regents of the University of California. All rights reserved.
|
||||
Modified: 2002 R. Oktas, <roktas@omu.edu.tr>
|
||||
**********/
|
||||
|
||||
#include <config.h>
|
||||
|
|
@ -14,11 +15,30 @@ Copyright 1991 Regents of the University of California. All rights reserved.
|
|||
#include <pwd.h>
|
||||
#endif
|
||||
|
||||
/* XXX To prevent a name collision with `readline's `tilde_expand',
|
||||
the original name: `tilde_expand' has changed to `tildexpand'. This
|
||||
situation naturally brings to mind that `tilde_expand' could be used
|
||||
directly from `readline' (since it will already be included if we
|
||||
wish to activate the `readline' support). Following implementation of
|
||||
'tilde expanding' has some problems which constitutes another good
|
||||
reason why it should be replaced: eg. it returns NULL which should
|
||||
not behave this way, IMHO. Anyway... Don't care for the moment, may
|
||||
be in the future. -- ro */
|
||||
|
||||
|
||||
/* PN: Since readline patch is not compiled in by default the behaviour
|
||||
described above is not acceptable. I will make two different version
|
||||
of tilde expansion routine, the one choosen depends on HAVE_GNUREADLINE
|
||||
Note: since a readline replacement called libedit is under
|
||||
development at libedit.sourceforge.net, I will switch to it
|
||||
ASAP, since libedit is covered by BSD licnse.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef HAVE_GNUREADLINE
|
||||
char *
|
||||
tilde_expand(char *string)
|
||||
{
|
||||
|
||||
#ifdef HAVE_PWD_H
|
||||
struct passwd *pw;
|
||||
/*extern struct passwd *getpwuid( );*/
|
||||
|
|
@ -60,3 +80,63 @@ tilde_expand(char *string)
|
|||
return copy(string);
|
||||
#endif
|
||||
}
|
||||
|
||||
#else /* HAVE_GNUREADLINE */
|
||||
|
||||
char *
|
||||
tildexpand(char *string)
|
||||
{
|
||||
|
||||
char buf[BSIZE_SP];
|
||||
char *result, *k, c;
|
||||
if (!string)
|
||||
return NULL;
|
||||
|
||||
while (*string && isspace(*string))
|
||||
string++;
|
||||
|
||||
if (*string != '~')
|
||||
return copy(string);
|
||||
|
||||
string += 1;
|
||||
|
||||
if (!*string || *string == '/') {
|
||||
/* First try the environment setting. May also make life easier
|
||||
for non-unix platforms, eg. MS-DOS. -- ro */
|
||||
result = getenv("HOME");
|
||||
#ifdef HAVE_PWD_H
|
||||
/* Can't find a result from the environment, let's try
|
||||
the other stuff. -- ro */
|
||||
if (!result) {
|
||||
struct passwd *pw;
|
||||
pw = getpwuid(getuid());
|
||||
if (pw)
|
||||
result = pw->pw_dir;
|
||||
*buf = 0;
|
||||
}
|
||||
} else {
|
||||
struct passwd *pw;
|
||||
k = buf;
|
||||
while ((c = *string) && c != '/')
|
||||
*k++ = c, string++;
|
||||
*k = 0;
|
||||
pw = getpwnam(buf);
|
||||
if (pw)
|
||||
result = pw->pw_dir;
|
||||
#endif
|
||||
}
|
||||
if (result) {
|
||||
#ifdef HAVE_PWD_H
|
||||
strcpy(buf, result);
|
||||
if (*string)
|
||||
strcat(buf, string);
|
||||
return copy(buf);
|
||||
} else
|
||||
return NULL;
|
||||
#else
|
||||
|
||||
/* Emulate the old behavior to prevent side effects. -- ro */
|
||||
return copy(string);
|
||||
#endif
|
||||
}
|
||||
#endif /* HAVE_GNUREADLINE */
|
||||
|
|
|
|||
|
|
@ -6,7 +6,10 @@
|
|||
#ifndef TILDE_H_INCLUDED
|
||||
#define TILDE_H_INCLUDED
|
||||
|
||||
#ifdef HAVE_GNUREADLINE
|
||||
char * tildexpand(char *string);
|
||||
#else
|
||||
char * tilde_expand(char *string);
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Reference in New Issue