1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-04-29 19:30:36 +02:00

Fix broken interaction between readline and Unicode

This requires separate small fixes.

Readline has internal logic to deal with multi-byte characters, so
it wants bytes, not characters.

scm_c_read gets called by the vm when readline is activated, and it was
truncating multi-byte characters because soft ports didn't have the
UCS-4 capability.

Soft ports need the capability to read UCS-4 characters.  Since soft ports
may have a single byte buffer, full characters need to be stored into the
pushback buffer.

This broke the optimizations in scm_c_read for using an alternate buffer
for single-byte-buffered ports, because the opimization wasn't expecting
anything in the pushback buffer.

* libguile/vports.c (sf_fill_input): store complete chars, not single bytes

* libguile/ports.c (scm_c_read): don't use optimized path for non Latin-1.
  Add debug prints.

* libguile/string.h: make scm_i_from_stringn and scm_i_string_ref public
  so that readline can use them

* guile-readline/readline.c: read bytes, not complete chars, from the
  input port.  Convert output to the output port's locale
This commit is contained in:
Michael Gran 2009-09-07 18:42:29 -07:00
parent eebff6d7f1
commit 7519234547
4 changed files with 42 additions and 14 deletions

View file

@ -128,6 +128,7 @@ rl_free_line_state ()
static int promptp;
static SCM input_port;
static SCM output_port;
static SCM before_read;
static int
@ -138,7 +139,7 @@ current_input_getc (FILE *in SCM_UNUSED)
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;
@ -255,7 +256,12 @@ internal_readline (SCM text)
promptp = 1;
s = readline (prompt);
if (s)
ret = scm_from_locale_string (s);
{
scm_t_port *pt = SCM_PTAB_ENTRY (output_port);
ret = scm_i_from_stringn (s, strlen (s), pt->encoding,
SCM_FAILED_CONVERSION_ESCAPE_SEQUENCE);
}
else
ret = SCM_EOF_VAL;
@ -311,6 +317,7 @@ 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);