X-Git-Url: https://git.hcoop.net/bpt/guile.git/blobdiff_plain/6dc797eee9041498eec7053d32d8721c3660fb51..5dae693cb5f8f082b3188f3dc955d1f86fe6a50a:/guile-readline/readline.c diff --git a/guile-readline/readline.c b/guile-readline/readline.c index 5f6719dd7..aac6e18c2 100644 --- a/guile-readline/readline.c +++ b/guile-readline/readline.c @@ -1,6 +1,7 @@ /* readline.c --- line editing support for Guile */ -/* Copyright (C) 1997,1999,2000,2001, 2002, 2003, 2006, 2007, 2008, 2009 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 @@ -27,19 +28,13 @@ #ifdef HAVE_RL_GETC_FUNCTION #include "libguile.h" -#include "libguile/iselect.h" #include -#ifdef HAVE_UNISTD_H #include -#endif #include #include -#ifndef __MINGW32__ #include -#else -#include -#endif +#include #include #include "libguile/validate.h" @@ -146,7 +141,7 @@ 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); @@ -200,15 +195,15 @@ SCM_DEFINE (scm_readline, "%readline", 0, 4, 0, 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; @@ -231,19 +226,16 @@ reentry_barrier () 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 @@ -256,12 +248,7 @@ internal_readline (SCM text) promptp = 1; s = readline (prompt); if (s) - { - scm_t_port *pt = SCM_PTAB_ENTRY (output_port); - - ret = scm_from_stringn (s, strlen (s), pt->encoding, - SCM_FAILED_CONVERSION_ESCAPE_SEQUENCE); - } + ret = scm_from_port_string (s, output_port); else ret = SCM_EOF_VAL; @@ -318,10 +305,8 @@ scm_readline_init_ports (SCM inp, SCM outp) input_port = inp; output_port = outp; -#ifndef __MINGW32__ rl_instream = stream_from_fport (inp, "r", s_scm_readline); rl_outstream = stream_from_fport (outp, "w", s_scm_readline); -#endif } @@ -493,11 +478,9 @@ static int 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) @@ -508,14 +491,12 @@ match_paren (int x, int k) && 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) { @@ -524,12 +505,7 @@ match_paren (int x, int k) 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; } @@ -546,18 +522,26 @@ scm_init_readline () #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"; - 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); #if HAVE_RL_GET_KEYMAP