mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-04-30 20:00:19 +02:00
Merge remote-tracking branch 'origin/stable-2.0'
Conflicts: libguile/deprecated.c libguile/ports.c libguile/ports.h libguile/strports.c test-suite/tests/cse.test
This commit is contained in:
commit
0dd7c54075
26 changed files with 343 additions and 158 deletions
|
@ -372,7 +372,7 @@ SCM_DEFINE (scm_string_to_pointer, "string->pointer", 1, 1, 0,
|
|||
|
||||
ret = scm_from_pointer
|
||||
(scm_to_stringn (string, NULL, enc,
|
||||
scm_i_get_conversion_strategy (SCM_BOOL_F)),
|
||||
scm_i_default_port_conversion_handler ()),
|
||||
free);
|
||||
|
||||
scm_dynwind_end ();
|
||||
|
@ -417,7 +417,7 @@ SCM_DEFINE (scm_pointer_to_string, "pointer->string", 1, 2, 0,
|
|||
scm_dynwind_free (enc);
|
||||
|
||||
ret = scm_from_stringn (SCM_POINTER_VALUE (pointer), len, enc,
|
||||
scm_i_get_conversion_strategy (SCM_BOOL_F));
|
||||
scm_i_default_port_conversion_handler ());
|
||||
|
||||
scm_dynwind_end ();
|
||||
|
||||
|
|
198
libguile/ports.c
198
libguile/ports.c
|
@ -627,7 +627,7 @@ scm_c_make_port (scm_t_bits tag, unsigned long mode_bits, scm_t_bits stream)
|
|||
{
|
||||
return scm_c_make_port_with_encoding (tag, mode_bits,
|
||||
scm_i_default_port_encoding (),
|
||||
scm_i_get_conversion_strategy (SCM_BOOL_F),
|
||||
scm_i_default_port_conversion_handler (),
|
||||
stream);
|
||||
}
|
||||
|
||||
|
@ -847,6 +847,83 @@ scm_i_default_port_encoding (void)
|
|||
}
|
||||
}
|
||||
|
||||
/* A fluid specifying the default conversion handler for newly created
|
||||
ports. Its value should be one of the symbols below. */
|
||||
SCM_VARIABLE (default_conversion_strategy_var,
|
||||
"%default-port-conversion-strategy");
|
||||
|
||||
/* Whether the above fluid is initialized. */
|
||||
static int scm_conversion_strategy_init = 0;
|
||||
|
||||
/* The possible conversion strategies. */
|
||||
SCM_SYMBOL (sym_error, "error");
|
||||
SCM_SYMBOL (sym_substitute, "substitute");
|
||||
SCM_SYMBOL (sym_escape, "escape");
|
||||
|
||||
/* Return the default failed encoding conversion policy for new created
|
||||
ports. */
|
||||
scm_t_string_failed_conversion_handler
|
||||
scm_i_default_port_conversion_handler (void)
|
||||
{
|
||||
scm_t_string_failed_conversion_handler handler;
|
||||
|
||||
if (!scm_conversion_strategy_init
|
||||
|| !scm_is_fluid (SCM_VARIABLE_REF (default_conversion_strategy_var)))
|
||||
handler = SCM_FAILED_CONVERSION_QUESTION_MARK;
|
||||
else
|
||||
{
|
||||
SCM fluid, value;
|
||||
|
||||
fluid = SCM_VARIABLE_REF (default_conversion_strategy_var);
|
||||
value = scm_fluid_ref (fluid);
|
||||
|
||||
if (scm_is_eq (sym_substitute, value))
|
||||
handler = SCM_FAILED_CONVERSION_QUESTION_MARK;
|
||||
else if (scm_is_eq (sym_escape, value))
|
||||
handler = SCM_FAILED_CONVERSION_ESCAPE_SEQUENCE;
|
||||
else
|
||||
/* Default to 'error also when the fluid's value is not one of
|
||||
the valid symbols. */
|
||||
handler = SCM_FAILED_CONVERSION_ERROR;
|
||||
}
|
||||
|
||||
return handler;
|
||||
}
|
||||
|
||||
/* Use HANDLER as the default conversion strategy for future ports. */
|
||||
void
|
||||
scm_i_set_default_port_conversion_handler (scm_t_string_failed_conversion_handler
|
||||
handler)
|
||||
{
|
||||
SCM strategy;
|
||||
|
||||
if (!scm_conversion_strategy_init
|
||||
|| !scm_is_fluid (SCM_VARIABLE_REF (default_conversion_strategy_var)))
|
||||
scm_misc_error (NULL, "tried to set conversion strategy fluid before it is initialized",
|
||||
SCM_EOL);
|
||||
|
||||
switch (handler)
|
||||
{
|
||||
case SCM_FAILED_CONVERSION_ERROR:
|
||||
strategy = sym_error;
|
||||
break;
|
||||
|
||||
case SCM_FAILED_CONVERSION_ESCAPE_SEQUENCE:
|
||||
strategy = sym_escape;
|
||||
break;
|
||||
|
||||
case SCM_FAILED_CONVERSION_QUESTION_MARK:
|
||||
strategy = sym_substitute;
|
||||
break;
|
||||
|
||||
default:
|
||||
abort ();
|
||||
}
|
||||
|
||||
scm_fluid_set_x (SCM_VARIABLE_REF (default_conversion_strategy_var),
|
||||
strategy);
|
||||
}
|
||||
|
||||
static void
|
||||
finalize_iconv_descriptors (GC_PTR ptr, GC_PTR data)
|
||||
{
|
||||
|
@ -1031,65 +1108,6 @@ SCM_DEFINE (scm_set_port_encoding_x, "set-port-encoding!", 2, 0, 0,
|
|||
}
|
||||
#undef FUNC_NAME
|
||||
|
||||
|
||||
/* This determines how conversions handle unconvertible characters. */
|
||||
SCM_GLOBAL_VARIABLE (scm_conversion_strategy, "%port-conversion-strategy");
|
||||
static int scm_conversion_strategy_init = 0;
|
||||
|
||||
scm_t_string_failed_conversion_handler
|
||||
scm_i_get_conversion_strategy (SCM port)
|
||||
{
|
||||
SCM encoding;
|
||||
|
||||
if (scm_is_false (port))
|
||||
{
|
||||
if (!scm_conversion_strategy_init
|
||||
|| !scm_is_fluid (SCM_VARIABLE_REF (scm_conversion_strategy)))
|
||||
return SCM_FAILED_CONVERSION_QUESTION_MARK;
|
||||
else
|
||||
{
|
||||
encoding = scm_fluid_ref (SCM_VARIABLE_REF (scm_conversion_strategy));
|
||||
if (scm_is_false (encoding))
|
||||
return SCM_FAILED_CONVERSION_QUESTION_MARK;
|
||||
else
|
||||
return (scm_t_string_failed_conversion_handler) scm_to_int (encoding);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
scm_t_port *pt;
|
||||
pt = SCM_PTAB_ENTRY (port);
|
||||
return pt->ilseq_handler;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
scm_i_set_conversion_strategy_x (SCM port,
|
||||
scm_t_string_failed_conversion_handler handler)
|
||||
{
|
||||
SCM strategy;
|
||||
scm_t_port *pt;
|
||||
|
||||
strategy = scm_from_int ((int) handler);
|
||||
|
||||
if (scm_is_false (port))
|
||||
{
|
||||
/* Set the default encoding for future ports. */
|
||||
if (!scm_conversion_strategy_init
|
||||
|| !scm_is_fluid (SCM_VARIABLE_REF (scm_conversion_strategy)))
|
||||
scm_misc_error (NULL, "tried to set conversion strategy fluid before it is initialized",
|
||||
SCM_EOL);
|
||||
scm_fluid_set_x (SCM_VARIABLE_REF (scm_conversion_strategy), strategy);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Set the character encoding for this port. */
|
||||
pt = SCM_PTAB_ENTRY (port);
|
||||
pt->ilseq_handler = handler;
|
||||
}
|
||||
}
|
||||
|
||||
SCM_DEFINE (scm_port_conversion_strategy, "port-conversion-strategy",
|
||||
1, 0, 0, (SCM port),
|
||||
"Returns the behavior of the port when handling a character that\n"
|
||||
|
@ -1109,12 +1127,18 @@ SCM_DEFINE (scm_port_conversion_strategy, "port-conversion-strategy",
|
|||
|
||||
SCM_VALIDATE_OPPORT (1, port);
|
||||
|
||||
if (!scm_is_false (port))
|
||||
if (scm_is_false (port))
|
||||
h = scm_i_default_port_conversion_handler ();
|
||||
else
|
||||
{
|
||||
scm_t_port *pt;
|
||||
|
||||
SCM_VALIDATE_OPPORT (1, port);
|
||||
pt = SCM_PTAB_ENTRY (port);
|
||||
|
||||
h = pt->ilseq_handler;
|
||||
}
|
||||
|
||||
h = scm_i_get_conversion_strategy (port);
|
||||
if (h == SCM_FAILED_CONVERSION_ERROR)
|
||||
return scm_from_latin1_symbol ("error");
|
||||
else if (h == SCM_FAILED_CONVERSION_QUESTION_MARK)
|
||||
|
@ -1149,40 +1173,25 @@ SCM_DEFINE (scm_set_port_conversion_strategy_x, "set-port-conversion-strategy!",
|
|||
"this thread.\n")
|
||||
#define FUNC_NAME s_scm_set_port_conversion_strategy_x
|
||||
{
|
||||
SCM err;
|
||||
SCM qm;
|
||||
SCM esc;
|
||||
scm_t_string_failed_conversion_handler handler;
|
||||
|
||||
if (!scm_is_false (port))
|
||||
if (scm_is_eq (sym, sym_error))
|
||||
handler = SCM_FAILED_CONVERSION_ERROR;
|
||||
else if (scm_is_eq (sym, sym_substitute))
|
||||
handler = SCM_FAILED_CONVERSION_QUESTION_MARK;
|
||||
else if (scm_is_eq (sym, sym_escape))
|
||||
handler = SCM_FAILED_CONVERSION_ESCAPE_SEQUENCE;
|
||||
else
|
||||
SCM_MISC_ERROR ("unknown conversion strategy ~s", scm_list_1 (sym));
|
||||
|
||||
if (scm_is_false (port))
|
||||
scm_i_set_default_port_conversion_handler (handler);
|
||||
else
|
||||
{
|
||||
SCM_VALIDATE_OPPORT (1, port);
|
||||
SCM_PTAB_ENTRY (port)->ilseq_handler = handler;
|
||||
}
|
||||
|
||||
err = scm_from_latin1_symbol ("error");
|
||||
if (scm_is_true (scm_eqv_p (sym, err)))
|
||||
{
|
||||
scm_i_set_conversion_strategy_x (port, SCM_FAILED_CONVERSION_ERROR);
|
||||
return SCM_UNSPECIFIED;
|
||||
}
|
||||
|
||||
qm = scm_from_latin1_symbol ("substitute");
|
||||
if (scm_is_true (scm_eqv_p (sym, qm)))
|
||||
{
|
||||
scm_i_set_conversion_strategy_x (port,
|
||||
SCM_FAILED_CONVERSION_QUESTION_MARK);
|
||||
return SCM_UNSPECIFIED;
|
||||
}
|
||||
|
||||
esc = scm_from_latin1_symbol ("escape");
|
||||
if (scm_is_true (scm_eqv_p (sym, esc)))
|
||||
{
|
||||
scm_i_set_conversion_strategy_x (port,
|
||||
SCM_FAILED_CONVERSION_ESCAPE_SEQUENCE);
|
||||
return SCM_UNSPECIFIED;
|
||||
}
|
||||
|
||||
SCM_MISC_ERROR ("unknown conversion behavior ~s", scm_list_1 (sym));
|
||||
|
||||
return SCM_UNSPECIFIED;
|
||||
}
|
||||
#undef FUNC_NAME
|
||||
|
@ -2857,11 +2866,10 @@ scm_init_ports ()
|
|||
scm_make_fluid_with_default (SCM_BOOL_F));
|
||||
scm_port_encoding_init = 1;
|
||||
|
||||
SCM_VARIABLE_SET (scm_conversion_strategy,
|
||||
scm_make_fluid_with_default
|
||||
(scm_from_int ((int) SCM_FAILED_CONVERSION_QUESTION_MARK)));
|
||||
SCM_VARIABLE_SET (default_conversion_strategy_var,
|
||||
scm_make_fluid_with_default (sym_substitute));
|
||||
scm_conversion_strategy_init = 1;
|
||||
|
||||
|
||||
/* These bindings are used when boot-9 turns `current-input-port' et
|
||||
al into parameters. They are then removed from the guile module. */
|
||||
scm_c_define ("%current-input-port-fluid", cur_inport_fluid);
|
||||
|
|
|
@ -297,13 +297,14 @@ SCM_API SCM scm_close_output_port (SCM port);
|
|||
characters. */
|
||||
SCM_INTERNAL const char *scm_i_default_port_encoding (void);
|
||||
SCM_INTERNAL void scm_i_set_default_port_encoding (const char *);
|
||||
SCM_INTERNAL scm_t_string_failed_conversion_handler
|
||||
scm_i_default_port_conversion_handler (void);
|
||||
SCM_INTERNAL void
|
||||
scm_i_set_default_port_conversion_handler (scm_t_string_failed_conversion_handler);
|
||||
SCM_INTERNAL scm_t_iconv_descriptors *scm_i_port_iconv_descriptors (SCM port);
|
||||
SCM_INTERNAL void scm_i_set_port_encoding_x (SCM port, const char *str);
|
||||
SCM_API SCM scm_port_encoding (SCM port);
|
||||
SCM_API SCM scm_set_port_encoding_x (SCM port, SCM encoding);
|
||||
SCM_INTERNAL scm_t_string_failed_conversion_handler scm_i_get_conversion_strategy (SCM port);
|
||||
SCM_INTERNAL void scm_i_set_conversion_strategy_x (SCM port,
|
||||
scm_t_string_failed_conversion_handler h);
|
||||
SCM_API SCM scm_port_conversion_strategy (SCM port);
|
||||
SCM_API SCM scm_set_port_conversion_strategy_x (SCM port, SCM behavior);
|
||||
|
||||
|
|
|
@ -60,6 +60,9 @@
|
|||
|
||||
/* Character printers. */
|
||||
|
||||
#define PORT_CONVERSION_HANDLER(port) \
|
||||
SCM_PTAB_ENTRY (port)->ilseq_handler
|
||||
|
||||
static size_t display_string (const void *, int, size_t, SCM,
|
||||
scm_t_string_failed_conversion_handler);
|
||||
|
||||
|
@ -417,7 +420,7 @@ print_normal_symbol (SCM sym, SCM port)
|
|||
scm_t_string_failed_conversion_handler strategy;
|
||||
|
||||
len = scm_i_symbol_length (sym);
|
||||
strategy = scm_i_get_conversion_strategy (port);
|
||||
strategy = SCM_PTAB_ENTRY (port)->ilseq_handler;
|
||||
|
||||
if (scm_i_is_narrow_symbol (sym))
|
||||
display_string (scm_i_symbol_chars (sym), 1, len, port, strategy);
|
||||
|
@ -432,7 +435,7 @@ print_extended_symbol (SCM sym, SCM port)
|
|||
scm_t_string_failed_conversion_handler strategy;
|
||||
|
||||
len = scm_i_symbol_length (sym);
|
||||
strategy = scm_i_get_conversion_strategy (port);
|
||||
strategy = PORT_CONVERSION_HANDLER (port);
|
||||
|
||||
scm_lfwrite_unlocked ("#{", 2, port);
|
||||
|
||||
|
@ -539,7 +542,7 @@ iprin1 (SCM exp, SCM port, scm_print_state *pstate)
|
|||
else
|
||||
{
|
||||
if (!display_character (SCM_CHAR (exp), port,
|
||||
scm_i_get_conversion_strategy (port)))
|
||||
PORT_CONVERSION_HANDLER (port)))
|
||||
scm_encoding_error (__func__, errno,
|
||||
"cannot convert to output locale",
|
||||
port, exp);
|
||||
|
@ -625,7 +628,7 @@ iprin1 (SCM exp, SCM port, scm_print_state *pstate)
|
|||
printed = display_string (scm_i_string_data (exp),
|
||||
scm_i_is_narrow_string (exp),
|
||||
len, port,
|
||||
scm_i_get_conversion_strategy (port));
|
||||
PORT_CONVERSION_HANDLER (port));
|
||||
if (SCM_UNLIKELY (printed < len))
|
||||
scm_encoding_error (__func__, errno,
|
||||
"cannot convert to output locale",
|
||||
|
@ -1178,7 +1181,7 @@ write_character (scm_t_wchar ch, SCM port, int string_escapes_p)
|
|||
int printed = 0;
|
||||
scm_t_string_failed_conversion_handler strategy;
|
||||
|
||||
strategy = scm_i_get_conversion_strategy (port);
|
||||
strategy = PORT_CONVERSION_HANDLER (port);
|
||||
|
||||
if (string_escapes_p)
|
||||
{
|
||||
|
@ -1539,7 +1542,7 @@ SCM_DEFINE (scm_write_char, "write-char", 1, 1, 0,
|
|||
|
||||
port = SCM_COERCE_OUTPORT (port);
|
||||
if (!display_character (SCM_CHAR (chr), port,
|
||||
scm_i_get_conversion_strategy (port)))
|
||||
PORT_CONVERSION_HANDLER (port)))
|
||||
scm_encoding_error (__func__, errno,
|
||||
"cannot convert to output locale",
|
||||
port, chr);
|
||||
|
|
|
@ -1578,7 +1578,7 @@ SCM
|
|||
scm_from_locale_stringn (const char *str, size_t len)
|
||||
{
|
||||
return scm_from_stringn (str, len, locale_charset (),
|
||||
scm_i_get_conversion_strategy (SCM_BOOL_F));
|
||||
scm_i_default_port_conversion_handler ());
|
||||
}
|
||||
|
||||
SCM
|
||||
|
@ -1877,9 +1877,9 @@ scm_to_locale_string (SCM str)
|
|||
char *
|
||||
scm_to_locale_stringn (SCM str, size_t *lenp)
|
||||
{
|
||||
return scm_to_stringn (str, lenp,
|
||||
return scm_to_stringn (str, lenp,
|
||||
locale_charset (),
|
||||
scm_i_get_conversion_strategy (SCM_BOOL_F));
|
||||
scm_i_default_port_conversion_handler ());
|
||||
}
|
||||
|
||||
char *
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
/* Copyright (C) 1995,1996,1998,1999,2000,2001,2002, 2003, 2005, 2006, 2009, 2010, 2011, 2012 Free Software Foundation, Inc.
|
||||
*
|
||||
/* Copyright (C) 1995, 1996, 1998, 1999, 2000, 2001, 2002, 2003, 2005, 2006,
|
||||
* 2009, 2010, 2011, 2012 Free Software Foundation, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public License
|
||||
* as published by the Free Software Foundation; either version 3 of
|
||||
|
@ -292,10 +293,11 @@ scm_mkstrport (SCM pos, SCM str, long modes, const char *caller)
|
|||
|
||||
z = scm_c_make_port_with_encoding (scm_tc16_strport, modes,
|
||||
encoding,
|
||||
SCM_FAILED_CONVERSION_ERROR,
|
||||
scm_i_default_port_conversion_handler (),
|
||||
(scm_t_bits)buf);
|
||||
|
||||
pt = SCM_PTAB_ENTRY (z);
|
||||
|
||||
pt->write_buf = pt->read_buf = (unsigned char *) c_buf;
|
||||
pt->read_pos = pt->write_pos = pt->read_buf + c_pos;
|
||||
pt->read_buf_size = read_buf_size;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue