/* readline.c --- line editing support for Guile */
-/* Copyright (C) 1997,1999,2000,2001, 2002, 2003 Free Software Foundation, Inc.
+/* Copyright (C) 1997,1999,2000,2001, 2002, 2003, 2006, 2007, 2008, 2009, 2010, 2013 Free Software Foundation, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
+ * the Free Software Foundation; either version 3, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
\f
-
-#if HAVE_CONFIG_H
-# include <config.h>
+#ifdef HAVE_CONFIG_H
+# include <config.h>
#endif
-#include "libguile/_scm.h"
#ifdef HAVE_RL_GETC_FUNCTION
#include "libguile.h"
-#include "libguile/gh.h"
-#include "libguile/iselect.h"
#include <stdio.h>
-#ifdef HAVE_UNISTD_H
#include <unistd.h>
-#endif
#include <readline/readline.h>
#include <readline/history.h>
-#ifndef __MINGW32__
#include <sys/time.h>
-#else
-#include <io.h>
-#endif
+#include <sys/select.h>
#include <signal.h>
#include "libguile/validate.h"
{ SCM_OPTION_INTEGER, "history-length", 200,
"History length." },
{ SCM_OPTION_INTEGER, "bounce-parens", 500,
- "Time (ms) to show matching opening parenthesis (0 = off)."}
+ "Time (ms) to show matching opening parenthesis (0 = off)."},
+ { 0 }
};
extern void stifle_history (int max);
{
SCM ans = scm_options (setting,
scm_readline_opts,
- SCM_N_READLINE_OPTIONS,
FUNC_NAME);
stifle_history (SCM_HISTORY_LENGTH);
return ans;
static int promptp;
static SCM input_port;
+static SCM output_port;
static SCM before_read;
static int
scm_apply (before_read, SCM_EOL, SCM_EOL);
promptp = 0;
}
- return scm_getc (input_port);
+ return scm_get_byte_or_eof (input_port);
}
static int in_readline = 0;
static SCM reentry_barrier_mutex;
static SCM internal_readline (SCM text);
-static SCM handle_error (void *data, SCM tag, SCM args);
+static void unwind_readline (void *unused);
static void reentry_barrier (void);
scm_readline_init_ports (inp, outp);
- ans = scm_internal_catch (SCM_BOOL_T,
- (scm_t_catch_body) internal_readline,
- (void *) SCM_UNPACK (text),
- handle_error, 0);
+ scm_dynwind_begin (0);
+ scm_dynwind_unwind_handler (unwind_readline, NULL, 0);
+
+ ans = internal_readline (text);
+
+ scm_dynwind_end ();
-#ifndef __MINGW32__
fclose (rl_instream);
fclose (rl_outstream);
-#endif
--in_readline;
return ans;
scm_misc_error (s_scm_readline, "readline is not reentrant", SCM_EOL);
}
-static SCM
-handle_error (void *data, SCM tag, SCM args)
+/* This function is only called on nonlocal exit from readline(). */
+static void
+unwind_readline (void *unused)
{
rl_free_line_state ();
rl_cleanup_after_signal ();
fputc ('\n', rl_outstream); /* We don't want next output on this line */
-#ifndef __MINGW32__
fclose (rl_instream);
fclose (rl_outstream);
-#endif
--in_readline;
- scm_handle_by_throw (data, tag, args);
- return SCM_UNSPECIFIED; /* never reached */
}
static SCM
promptp = 1;
s = readline (prompt);
if (s)
- ret = scm_from_locale_string (s);
+ {
+ scm_t_port *pt = SCM_PTAB_ENTRY (output_port);
+
+ ret = scm_from_stringn (s, strlen (s), pt->encoding,
+ SCM_FAILED_CONVERSION_ESCAPE_SEQUENCE);
+ }
else
ret = SCM_EOF_VAL;
}
input_port = inp;
-#ifndef __MINGW32__
+ output_port = outp;
rl_instream = stream_from_fport (inp, "r", s_scm_readline);
rl_outstream = stream_from_fport (outp, "w", s_scm_readline);
-#endif
}
s = scm_to_locale_string (text);
add_history (s);
+ free (s);
return SCM_UNSPECIFIED;
}
}
}
+#if HAVE_RL_GET_KEYMAP
/*Bouncing parenthesis (reimplemented by GH, 11/23/98, since readline is strict gpl)*/
static int match_paren (int x, int k);
match_paren (int x, int k)
{
int tmp;
-#ifndef __MINGW32__
int fno;
- SELECT_TYPE readset;
+ fd_set readset;
struct timeval timeout;
-#endif
rl_insert (x, k);
if (!SCM_READLINE_BOUNCE_PARENS)
&& rl_line_buffer[rl_point - 2] == '\\')
return 0;
-#ifndef __MINGW32__
tmp = 1000 * SCM_READLINE_BOUNCE_PARENS;
timeout.tv_sec = tmp / 1000000;
timeout.tv_usec = tmp % 1000000;
FD_ZERO (&readset);
fno = fileno (rl_instream);
FD_SET (fno, &readset);
-#endif
if (rl_point > 1)
{
if (rl_point > -1)
{
rl_redisplay ();
-#ifndef __MINGW32__
- scm_std_select (fno + 1, &readset, NULL, NULL, &timeout);
-#else
- WaitForSingleObject (GetStdHandle(STD_INPUT_HANDLE),
- SCM_READLINE_BOUNCE_PARENS);
-#endif
+ select (fno + 1, &readset, NULL, NULL, &timeout);
}
rl_point = tmp;
}
return 0;
}
-
-#if defined (HAVE_RL_PRE_INPUT_HOOK) && defined (GUILE_SIGWINCH_SA_RESTART_CLEARED)
-/* Readline disables SA_RESTART on SIGWINCH.
- * This code turns it back on.
- */
-static int
-sigwinch_enable_restart (void)
-{
-#ifdef HAVE_SIGINTERRUPT
- siginterrupt (SIGWINCH, 0);
-#else
- struct sigaction action;
-
- sigaction (SIGWINCH, NULL, &action);
- action.sa_flags |= SA_RESTART;
- sigaction (SIGWINCH, &action, NULL);
-#endif
- return 0;
-}
-#endif
+#endif /* HAVE_RL_GET_KEYMAP */
#endif /* HAVE_RL_GETC_FUNCTION */
#include "guile-readline/readline.x"
scm_readline_completion_function_var
= scm_c_define ("*readline-completion-function*", SCM_BOOL_F);
-#ifndef __MINGW32__
rl_getc_function = current_input_getc;
-#endif
#if defined (_RL_FUNCTION_TYPEDEF)
rl_completion_entry_function = (rl_compentry_func_t*) completion_function;
#else
rl_completion_entry_function = (Function*) completion_function;
#endif
- rl_basic_word_break_characters = "\t\n\"'`;()";
+ rl_basic_word_break_characters = " \t\n\"'`;()";
rl_readline_name = "Guile";
-#if defined (HAVE_RL_PRE_INPUT_HOOK) && defined (GUILE_SIGWINCH_SA_RESTART_CLEARED)
- rl_pre_input_hook = sigwinch_enable_restart;
-#endif
- reentry_barrier_mutex = scm_permanent_object (scm_make_mutex ());
+ /* Let Guile handle signals. */
+#if defined (HAVE_DECL_RL_CATCH_SIGNALS) && HAVE_DECL_RL_CATCH_SIGNALS
+ rl_catch_signals = 0;
+#endif
+
+ /* But let readline handle SIGWINCH. */
+#if defined (HAVE_DECL_RL_CATCH_SIGWINCH) && HAVE_DECL_RL_CATCH_SIGWINCH
+ rl_catch_sigwinch = 1;
+#endif
+
+ reentry_barrier_mutex = scm_make_mutex ();
scm_init_opts (scm_readline_options,
- scm_readline_opts,
- SCM_N_READLINE_OPTIONS);
+ scm_readline_opts);
+#if HAVE_RL_GET_KEYMAP
init_bouncing_parens();
+#endif
scm_add_feature ("readline");
#endif /* HAVE_RL_GETC_FUNCTION */
}