This commit is contained in:
Vítor Santos Costa 2015-11-10 14:13:56 +00:00
parent cddb8191c8
commit a3c09d66be

View File

@ -8,7 +8,7 @@
* * * *
************************************************************************** **************************************************************************
* * * *
* File: readline.c * * File: readline.c *
* Last rev: 5/2/88 * * Last rev: 5/2/88 *
* mods: * * mods: *
* comments: Input/Output C implemented predicates * * comments: Input/Output C implemented predicates *
@ -19,7 +19,8 @@ static char SccsId[] = "%W% %G%";
#endif #endif
/* /*
* This file includes the interface to the readline library, if installed in the system. * This file includes the interface to the readline library, if installed in the
*system.
* *
*/ */
@ -44,7 +45,7 @@ static char SccsId[] = "%W% %G%";
#endif #endif
#include <windows.h> #include <windows.h>
#ifndef S_ISDIR #ifndef S_ISDIR
#define S_ISDIR(x) (((x)&_S_IFDIR)==_S_IFDIR) #define S_ISDIR(x) (((x)&_S_IFDIR) == _S_IFDIR)
#endif #endif
#endif #endif
@ -55,8 +56,10 @@ static char SccsId[] = "%W% %G%";
#include <readline/readline.h> #include <readline/readline.h>
#include <readline/history.h> #include <readline/history.h>
static int ReadlineGetc( int); static int ReadlineGetc(int);
static int ReadlinePutc( int,int); static int ReadlinePutc(int, int);
static const char *history_file;
#define READLINE_OUT_BUF_MAX 256 #define READLINE_OUT_BUF_MAX 256
@ -65,29 +68,26 @@ typedef struct scan_atoms {
Atom atom; Atom atom;
} scan_atoms_t; } scan_atoms_t;
static char * static char *atom_enumerate(const char *prefix, int state) {
atom_enumerate(const char *prefix, int state) CACHE_REGS
{
CACHE_REGS
struct scan_atoms *index; struct scan_atoms *index;
Atom catom; Atom catom;
Int i; Int i;
if ( !state ) if (!state) {
{ index = (struct scan_atoms *)malloc(sizeof(struct scan_atoms)); index = (struct scan_atoms *)malloc(sizeof(struct scan_atoms));
i = 0; i = 0;
catom = NIL; catom = NIL;
} else } else {
{ CACHE_REGS
CACHE_REGS index = LOCAL_search_atoms;
index = LOCAL_search_atoms;
catom = index->atom; catom = index->atom;
i = index->pos; i = index->pos;
} }
while (catom != NIL || i < AtomHashTableSize) { while (catom != NIL || i < AtomHashTableSize) {
// if ( is_signalled() ) /* Notably allow windows version */ // if ( is_signalled() ) /* Notably allow windows version */
// PL_handle_signals(); /* to break out on ^C */ // PL_handle_signals(); /* to break out on ^C */
AtomEntry *ap; AtomEntry *ap;
if (catom == NIL) { if (catom == NIL) {
@ -99,12 +99,12 @@ atom_enumerate(const char *prefix, int state)
} else { } else {
ap = RepAtom(catom); ap = RepAtom(catom);
READ_LOCK(ap->ARWLock); READ_LOCK(ap->ARWLock);
if ( strstr( (char *)ap->StrOfAE, prefix) == ( char *)ap->StrOfAE) { if (strstr((char *)ap->StrOfAE, prefix) == (char *)ap->StrOfAE) {
index->pos = i; index->pos = i;
index->atom = ap->NextOfAE; index->atom = ap->NextOfAE;
LOCAL_search_atoms = index; LOCAL_search_atoms = index;
READ_UNLOCK(ap->ARWLock); READ_UNLOCK(ap->ARWLock);
return ap->StrOfAE; return ap->StrOfAE;
} }
catom = ap->NextOfAE; catom = ap->NextOfAE;
READ_UNLOCK(ap->ARWLock); READ_UNLOCK(ap->ARWLock);
@ -115,15 +115,13 @@ atom_enumerate(const char *prefix, int state)
return NULL; return NULL;
} }
static char *atom_generator(const char *prefix, int state) {
char *s = atom_enumerate(prefix, state);
static char * if (s) {
atom_generator(const char *prefix, int state) char *copy = malloc(1 + strlen(s));
{ char *s = atom_enumerate(prefix, state);
if ( s ) if (copy) /* else pretend no completion */
{ char *copy = malloc(1 + strlen(s));
if ( copy ) /* else pretend no completion */
strcpy(copy, s); strcpy(copy, s);
s = copy; s = copy;
} }
@ -131,51 +129,41 @@ atom_generator(const char *prefix, int state)
return s; return s;
} }
static char **prolog_completion(const char *text, int start, int end) {
char **matches = NULL;
static char ** if ((start == 1 && rl_line_buffer[0] == '[') || /* [file */
prolog_completion(const char *text, int start, int end) (start == 2 && strncmp(rl_line_buffer, "['", 2)))
{ char **matches = NULL; matches = rl_completion_matches((char *)text, /* for pre-4.2 */
rl_filename_completion_function);
if ( (start == 1 && rl_line_buffer[0] == '[') || /* [file */
(start == 2 && strncmp(rl_line_buffer, "['", 2)) )
matches = rl_completion_matches((char *)text, /* for pre-4.2 */
rl_filename_completion_function);
else else
matches = rl_completion_matches((char *)text, matches = rl_completion_matches((char *)text, atom_generator);
atom_generator);
return matches; return matches;
} }
void Yap_ReadlineFlush(int sno) {
void if (GLOBAL_Stream[sno].status & Tty_Stream_f &&
Yap_ReadlineFlush( int sno )
{
if (GLOBAL_Stream[sno].status & Tty_Stream_f &&
GLOBAL_Stream[sno].status & Output_Stream_f) { GLOBAL_Stream[sno].status & Output_Stream_f) {
rl_redisplay(); rl_redisplay();
} }
} }
bool Yap_ReadlinePrompt( StreamDesc * s ) bool Yap_ReadlinePrompt(StreamDesc *s) {
{
if (s->status & Tty_Stream_f) { if (s->status & Tty_Stream_f) {
s->stream_getc = ReadlineGetc; s->stream_getc = ReadlineGetc;
if (GLOBAL_Stream[0].status & Tty_Stream_f && if (GLOBAL_Stream[0].status & Tty_Stream_f &&
s->name == GLOBAL_Stream[0].name) s->name == GLOBAL_Stream[0].name)
s->stream_putc = ReadlinePutc; s->stream_putc = ReadlinePutc;
return true; return true;
} }
return false; return false;
} }
bool bool Yap_ReadlineOps(StreamDesc *s) {
Yap_ReadlineOps( StreamDesc *s )
{
if (s->status & Tty_Stream_f) { if (s->status & Tty_Stream_f) {
if (GLOBAL_Stream[0].status & Tty_Stream_f && if (GLOBAL_Stream[0].status & Tty_Stream_f &&
is_same_tty(s->file,GLOBAL_Stream[0].file)) is_same_tty(s->file, GLOBAL_Stream[0].file))
s->stream_putc = ReadlinePutc; s->stream_putc = ReadlinePutc;
s->stream_getc = ReadlineGetc; s->stream_getc = ReadlineGetc;
return true; return true;
@ -183,17 +171,14 @@ Yap_ReadlineOps( StreamDesc *s )
return false; return false;
} }
static int prolog_complete(int ignore, int key) {
static int if (rl_point > 0 && rl_line_buffer[rl_point - 1] != ' ') {
prolog_complete(int ignore, int key) #if HAVE_DECL_RL_CATCH_SIGNALS_ /* actually version >= 1.2, or true readline \
{ if ( rl_point > 0 && rl_line_buffer[rl_point-1] != ' ' ) */
{ rl_begin_undo_group();
#if HAVE_DECL_RL_CATCH_SIGNALS_ /* actually version >= 1.2, or true readline */
rl_begin_undo_group();
rl_complete(ignore, key); rl_complete(ignore, key);
if ( rl_point > 0 && rl_line_buffer[rl_point-1] == ' ' ) if (rl_point > 0 && rl_line_buffer[rl_point - 1] == ' ') {
{ rl_delete_text(rl_point - 1, rl_point);
rl_delete_text(rl_point-1, rl_point);
rl_point -= 1; rl_point -= 1;
rl_delete(-1, key); rl_delete(-1, key);
} }
@ -205,10 +190,9 @@ prolog_complete(int ignore, int key)
return 0; return 0;
} }
static void static void InitReadline(void) {
InitReadline(void) {
// don't call readline within emacs // don't call readline within emacs
//if (getenv("ËMACS")) // if (getenv("ËMACS"))
// return; // return;
GLOBAL_Stream[StdInStream].u.irl.buf = NULL; GLOBAL_Stream[StdInStream].u.irl.buf = NULL;
GLOBAL_Stream[StdInStream].u.irl.ptr = NULL; GLOBAL_Stream[StdInStream].u.irl.ptr = NULL;
@ -217,14 +201,14 @@ InitReadline(void) {
#endif #endif
rl_outstream = stderr; rl_outstream = stderr;
using_history(); using_history();
char *s = Yap_AbsoluteFile("~/.YAP.history",NULL,true); char *s = Yap_AbsoluteFile("~/.YAP.history", NULL, true);
if (!read_history (s)) if (!read_history(s)) {
{ FILE *f = fopen(s, "w"); FILE *f = fopen(s, "w");
if (f) { if (f) {
fclose(f); fclose(f);
read_history (s); read_history(s);
}
} }
}
rl_readline_name = "Prolog"; rl_readline_name = "Prolog";
rl_attempted_completion_function = prolog_completion; rl_attempted_completion_function = prolog_completion;
#ifdef HAVE_RL_COMPLETION_FUNC_T #ifdef HAVE_RL_COMPLETION_FUNC_T
@ -232,17 +216,14 @@ InitReadline(void) {
#else #else
rl_add_defun("prolog-complete", (void *)prolog_complete, '\t'); rl_add_defun("prolog-complete", (void *)prolog_complete, '\t');
#endif #endif
} }
static bool static bool getLine(int inp, int out) {
getLine( int inp, int out ) CACHE_REGS
{
CACHE_REGS
rl_instream = GLOBAL_Stream[inp].file; rl_instream = GLOBAL_Stream[inp].file;
rl_outstream = GLOBAL_Stream[out].file; rl_outstream = GLOBAL_Stream[out].file;
const char *myrl_line; const char *myrl_line;
StreamDesc *s = GLOBAL_Stream+inp; StreamDesc *s = GLOBAL_Stream + inp;
if (!(s->status & Tty_Stream_f)) if (!(s->status & Tty_Stream_f))
return false; return false;
@ -252,14 +233,14 @@ getLine( int inp, int out )
if (GLOBAL_Stream[out].linepos == 0) { // no output so far if (GLOBAL_Stream[out].linepos == 0) { // no output so far
fflush(NULL); fflush(NULL);
myrl_line = readline (LOCAL_Prompt); myrl_line = readline(LOCAL_Prompt);
} else { } else {
LOCAL_PrologMode |= ConsoleGetcMode; LOCAL_PrologMode |= ConsoleGetcMode;
myrl_line = readline (NULL); myrl_line = readline(NULL);
} }
/* Do it the gnu way */ /* Do it the gnu way */
if (LOCAL_PrologMode & InterruptMode) { if (LOCAL_PrologMode & InterruptMode) {
Yap_external_signal( 0, YAP_INT_SIGNAL ); Yap_external_signal(0, YAP_INT_SIGNAL);
LOCAL_PrologMode &= ~ConsoleGetcMode; LOCAL_PrologMode &= ~ConsoleGetcMode;
if (LOCAL_PrologMode & AbortMode) { if (LOCAL_PrologMode & AbortMode) {
Yap_Error(ABORT_EVENT, TermNil, ""); Yap_Error(ABORT_EVENT, TermNil, "");
@ -269,57 +250,49 @@ getLine( int inp, int out )
} else { } else {
LOCAL_PrologMode &= ~ConsoleGetcMode; LOCAL_PrologMode &= ~ConsoleGetcMode;
} }
strncpy (LOCAL_Prompt, RepAtom (LOCAL_AtPrompt)->StrOfAE, MAX_PROMPT); strncpy(LOCAL_Prompt, RepAtom(LOCAL_AtPrompt)->StrOfAE, MAX_PROMPT);
/* window of vulnerability closed */ /* window of vulnerability closed */
if (myrl_line == NULL) if (myrl_line == NULL)
return false; return false;
if (myrl_line[0] != '\0' && myrl_line[1] != '\0') { if (myrl_line[0] != '\0' && myrl_line[1] != '\0') {
add_history (myrl_line); add_history(myrl_line);
write_history ( Yap_AbsoluteFile("~/.YAP.history", NULL, true)); append_history(1, history_file);
}
s->u.irl.ptr = s->u.irl.buf = myrl_line;
return true;
} }
s->u.irl.ptr = s->u.irl.buf = myrl_line;
static int return true;
ReadlinePutc (int sno, int ch)
{
StreamDesc *s = &GLOBAL_Stream[sno];
#if MAC || _MSC_VER || defined(__MINGW32__)
if (ch == 10)
{
putc ('\n', s->file);
}
else
#endif
putc (ch, s->file);
console_count_output_char(ch,s);
if (ch == 10) {
Yap_ReadlineFlush( sno );
}
return ((int) ch);
} }
static int ReadlinePutc(int sno, int ch) {
StreamDesc *s = &GLOBAL_Stream[sno];
#if MAC || _MSC_VER || defined(__MINGW32__)
if (ch == 10) {
putc('\n', s->file);
} else
#endif
putc(ch, s->file);
console_count_output_char(ch, s);
if (ch == 10) {
Yap_ReadlineFlush(sno);
}
return ((int)ch);
}
/* /*
reading from the console is complicated because we need to reading from the console is complicated because we need to
know whether to prompt and so on... know whether to prompt and so on...
*/ */
static int static int ReadlineGetc(int sno) {
ReadlineGetc(int sno)
{
StreamDesc *s = &GLOBAL_Stream[sno]; StreamDesc *s = &GLOBAL_Stream[sno];
int ch; int ch;
bool fetch = (s->u.irl.buf == NULL); bool fetch = (s->u.irl.buf == NULL);
if (!fetch || getLine( sno, StdErrStream ) ) { if (!fetch || getLine(sno, StdErrStream)) {
const char *ttyptr = s->u.irl.ptr++, *myrl_line = s->u.irl.buf; const char *ttyptr = s->u.irl.ptr++, *myrl_line = s->u.irl.buf;
ch = *ttyptr; ch = *ttyptr;
if (ch == '\0') { if (ch == '\0') {
ch = '\n'; ch = '\n';
free ((void *)myrl_line); free((void *)myrl_line);
s->u.irl.ptr = s->u.irl.buf = NULL; s->u.irl.ptr = s->u.irl.buf = NULL;
} }
} else { } else {
return EOF; return EOF;
@ -327,21 +300,19 @@ ReadlineGetc(int sno)
return console_post_process_read_char(ch, s); return console_post_process_read_char(ch, s);
} }
int int Yap_ReadlineForSIGINT(void) {
Yap_ReadlineForSIGINT(void) CACHE_REGS
{
CACHE_REGS
int ch; int ch;
StreamDesc *s = &GLOBAL_Stream[StdInStream]; StreamDesc *s = &GLOBAL_Stream[StdInStream];
const char *myrl_line = s->u.irl.buf; const char *myrl_line = s->u.irl.buf;
if ((LOCAL_PrologMode & ConsoleGetcMode) && myrl_line != (char *) NULL) { if ((LOCAL_PrologMode & ConsoleGetcMode) && myrl_line != (char *)NULL) {
ch = myrl_line[0]; ch = myrl_line[0];
free((void *)myrl_line); free((void *)myrl_line);
myrl_line = NULL; myrl_line = NULL;
return ch; return ch;
} else { } else {
myrl_line = readline ("Action (h for help): "); myrl_line = readline("Action (h for help): ");
if (!myrl_line) { if (!myrl_line) {
ch = EOF; ch = EOF;
return ch; return ch;
@ -354,8 +325,7 @@ Yap_ReadlineForSIGINT(void)
} }
} }
static Int has_readline(USES_REGS1) static Int has_readline(USES_REGS1) {
{
#if USE_READLINE #if USE_READLINE
return true; return true;
#else #else
@ -363,9 +333,9 @@ static Int has_readline(USES_REGS1)
#endif #endif
} }
void Yap_InitReadline(void) { void Yap_InitReadline(void) {
Yap_InitCPred ("$has_readline", 0, has_readline, SafePredFlag|HiddenPredFlag); Yap_InitCPred("$has_readline", 0, has_readline,
SafePredFlag | HiddenPredFlag);
InitReadline(); InitReadline();
} }