mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-04-30 03:40:34 +02:00
Load port bindings in separate (ice-9 ports) module
* module/ice-9/ports.scm: New file. * am/bootstrap.am (SOURCES): Add ice-9/ports.scm. * libguile/fports.c (scm_init_ice_9_fports): New function. (scm_init_fports): Arrange for scm_init_ice_9_fports to be called via load-extension, and load snarfed things there. Move open-file definition early, to allow ports to bootstrap. * libguile/ioext.c (scm_init_ice_9_ioext): New function. (scm_init_ioext): Similarly, register scm_init_ice_9_ioext as an extension. * libguile/ports.c (scm_set_current_input_port) (scm_set_current_output_port, scm_set_current_error_port): Don't define Scheme bindings; do that in Scheme. * libguile/ports.c (scm_i_set_default_port_encoding): (scm_i_default_port_encoding, scm_i_default_port_conversion_handler): (scm_i_set_default_port_conversion_handler): Since we now init encoding early, remove the "init" flags on these encoding/strategy vars. (scm_init_ice_9_ports): New function. (scm_init_ports): Register scm_init_ice_9_ports extension, and define some bindings needed by the bootstrap. * module/Makefile.am (SOURCES): Add ice-9/ports.scm. * module/ice-9/boot-9.scm: Remove code that's not on the boot path, moving it to ice-9/ports.scm. At the end, load (ice-9 ports). * module/ice-9/psyntax.scm (include): Use close-port instead of close-input-port. * module/ice-9/psyntax-pp.scm (include): Regenerate.
This commit is contained in:
parent
5e470ea48f
commit
44b3342c4d
9 changed files with 607 additions and 402 deletions
|
@ -123,6 +123,7 @@ SOURCES = \
|
||||||
system/base/ck.scm \
|
system/base/ck.scm \
|
||||||
\
|
\
|
||||||
ice-9/boot-9.scm \
|
ice-9/boot-9.scm \
|
||||||
|
ice-9/ports.scm \
|
||||||
ice-9/r5rs.scm \
|
ice-9/r5rs.scm \
|
||||||
ice-9/deprecated.scm \
|
ice-9/deprecated.scm \
|
||||||
ice-9/binary-ports.scm \
|
ice-9/binary-ports.scm \
|
||||||
|
|
|
@ -121,8 +121,8 @@ SCM_DEFINE (scm_file_port_p, "file-port?", 1, 0, 0,
|
||||||
|
|
||||||
|
|
||||||
static SCM sys_file_port_name_canonicalization;
|
static SCM sys_file_port_name_canonicalization;
|
||||||
SCM_SYMBOL (sym_relative, "relative");
|
static SCM sym_relative;
|
||||||
SCM_SYMBOL (sym_absolute, "absolute");
|
static SCM sym_absolute;
|
||||||
|
|
||||||
static SCM
|
static SCM
|
||||||
fport_canonicalize_filename (SCM filename)
|
fport_canonicalize_filename (SCM filename)
|
||||||
|
@ -677,16 +677,34 @@ scm_init_fports_keywords ()
|
||||||
k_encoding = scm_from_latin1_keyword ("encoding");
|
k_encoding = scm_from_latin1_keyword ("encoding");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
scm_init_ice_9_fports (void)
|
||||||
|
{
|
||||||
|
#include "libguile/fports.x"
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
scm_init_fports ()
|
scm_init_fports ()
|
||||||
{
|
{
|
||||||
scm_tc16_fport = scm_make_fptob ();
|
scm_tc16_fport = scm_make_fptob ();
|
||||||
|
|
||||||
|
scm_c_register_extension ("libguile-" SCM_EFFECTIVE_VERSION,
|
||||||
|
"scm_init_ice_9_fports",
|
||||||
|
(scm_t_extension_init_func) scm_init_ice_9_fports,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
/* The following bindings are used early in boot-9.scm. */
|
||||||
|
|
||||||
|
/* Used by `include' and also by `file-exists?' if `stat' is
|
||||||
|
unavailable. */
|
||||||
|
scm_c_define_gsubr (s_scm_i_open_file, 2, 0, 1, (scm_t_subr) scm_i_open_file);
|
||||||
|
|
||||||
|
/* Used by `open-file.', also via C. */
|
||||||
|
sym_relative = scm_from_latin1_symbol ("relative");
|
||||||
|
sym_absolute = scm_from_latin1_symbol ("absolute");
|
||||||
sys_file_port_name_canonicalization = scm_make_fluid ();
|
sys_file_port_name_canonicalization = scm_make_fluid ();
|
||||||
scm_c_define ("%file-port-name-canonicalization",
|
scm_c_define ("%file-port-name-canonicalization",
|
||||||
sys_file_port_name_canonicalization);
|
sys_file_port_name_canonicalization);
|
||||||
|
|
||||||
#include "libguile/fports.x"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -302,12 +302,21 @@ SCM_DEFINE (scm_fdes_to_ports, "fdes->ports", 1, 0, 0,
|
||||||
#undef FUNC_NAME
|
#undef FUNC_NAME
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
scm_init_ice_9_ioext (void)
|
||||||
|
{
|
||||||
|
#include "libguile/ioext.x"
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
scm_init_ioext ()
|
scm_init_ioext ()
|
||||||
{
|
{
|
||||||
scm_add_feature ("i/o-extensions");
|
scm_add_feature ("i/o-extensions");
|
||||||
|
|
||||||
#include "libguile/ioext.x"
|
scm_c_register_extension ("libguile-" SCM_EFFECTIVE_VERSION,
|
||||||
|
"scm_init_ice_9_ioext",
|
||||||
|
(scm_t_extension_init_func) scm_init_ice_9_ioext,
|
||||||
|
NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
186
libguile/ports.c
186
libguile/ports.c
|
@ -425,14 +425,9 @@ SCM_DEFINE (scm_current_load_port, "current-load-port", 0, 0, 0,
|
||||||
}
|
}
|
||||||
#undef FUNC_NAME
|
#undef FUNC_NAME
|
||||||
|
|
||||||
SCM_DEFINE (scm_set_current_input_port, "set-current-input-port", 1, 0, 0,
|
SCM
|
||||||
(SCM port),
|
scm_set_current_input_port (SCM port)
|
||||||
"@deffnx {Scheme Procedure} set-current-output-port port\n"
|
#define FUNC_NAME "set-current-input-port"
|
||||||
"@deffnx {Scheme Procedure} set-current-error-port port\n"
|
|
||||||
"Change the ports returned by @code{current-input-port},\n"
|
|
||||||
"@code{current-output-port} and @code{current-error-port}, respectively,\n"
|
|
||||||
"so that they use the supplied @var{port} for input or output.")
|
|
||||||
#define FUNC_NAME s_scm_set_current_input_port
|
|
||||||
{
|
{
|
||||||
SCM oinp = scm_fluid_ref (cur_inport_fluid);
|
SCM oinp = scm_fluid_ref (cur_inport_fluid);
|
||||||
SCM_VALIDATE_OPINPORT (1, port);
|
SCM_VALIDATE_OPINPORT (1, port);
|
||||||
|
@ -441,11 +436,9 @@ SCM_DEFINE (scm_set_current_input_port, "set-current-input-port", 1, 0, 0,
|
||||||
}
|
}
|
||||||
#undef FUNC_NAME
|
#undef FUNC_NAME
|
||||||
|
|
||||||
|
SCM
|
||||||
SCM_DEFINE (scm_set_current_output_port, "set-current-output-port", 1, 0, 0,
|
scm_set_current_output_port (SCM port)
|
||||||
(SCM port),
|
#define FUNC_NAME "scm-set-current-output-port"
|
||||||
"Set the current default output port to @var{port}.")
|
|
||||||
#define FUNC_NAME s_scm_set_current_output_port
|
|
||||||
{
|
{
|
||||||
SCM ooutp = scm_fluid_ref (cur_outport_fluid);
|
SCM ooutp = scm_fluid_ref (cur_outport_fluid);
|
||||||
port = SCM_COERCE_OUTPORT (port);
|
port = SCM_COERCE_OUTPORT (port);
|
||||||
|
@ -455,11 +448,9 @@ SCM_DEFINE (scm_set_current_output_port, "set-current-output-port", 1, 0, 0,
|
||||||
}
|
}
|
||||||
#undef FUNC_NAME
|
#undef FUNC_NAME
|
||||||
|
|
||||||
|
SCM
|
||||||
SCM_DEFINE (scm_set_current_error_port, "set-current-error-port", 1, 0, 0,
|
scm_set_current_error_port (SCM port)
|
||||||
(SCM port),
|
#define FUNC_NAME "set-current-error-port"
|
||||||
"Set the current default error port to @var{port}.")
|
|
||||||
#define FUNC_NAME s_scm_set_current_error_port
|
|
||||||
{
|
{
|
||||||
SCM oerrp = scm_fluid_ref (cur_errport_fluid);
|
SCM oerrp = scm_fluid_ref (cur_errport_fluid);
|
||||||
port = SCM_COERCE_OUTPORT (port);
|
port = SCM_COERCE_OUTPORT (port);
|
||||||
|
@ -469,7 +460,6 @@ SCM_DEFINE (scm_set_current_error_port, "set-current-error-port", 1, 0, 0,
|
||||||
}
|
}
|
||||||
#undef FUNC_NAME
|
#undef FUNC_NAME
|
||||||
|
|
||||||
|
|
||||||
SCM
|
SCM
|
||||||
scm_set_current_warning_port (SCM port)
|
scm_set_current_warning_port (SCM port)
|
||||||
#define FUNC_NAME "set-current-warning-port"
|
#define FUNC_NAME "set-current-warning-port"
|
||||||
|
@ -482,7 +472,6 @@ scm_set_current_warning_port (SCM port)
|
||||||
}
|
}
|
||||||
#undef FUNC_NAME
|
#undef FUNC_NAME
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
scm_dynwind_current_input_port (SCM port)
|
scm_dynwind_current_input_port (SCM port)
|
||||||
#define FUNC_NAME NULL
|
#define FUNC_NAME NULL
|
||||||
|
@ -916,19 +905,12 @@ SCM_DEFINE (scm_close_output_port, "close-output-port", 1, 0, 0,
|
||||||
/* A fluid specifying the default encoding for newly created ports. If it is
|
/* A fluid specifying the default encoding for newly created ports. If it is
|
||||||
a string, that is the encoding. If it is #f, it is in the "native"
|
a string, that is the encoding. If it is #f, it is in the "native"
|
||||||
(Latin-1) encoding. */
|
(Latin-1) encoding. */
|
||||||
SCM_VARIABLE (default_port_encoding_var, "%default-port-encoding");
|
static SCM default_port_encoding_var;
|
||||||
|
|
||||||
static int scm_port_encoding_init = 0;
|
|
||||||
|
|
||||||
/* Use ENCODING as the default encoding for future ports. */
|
/* Use ENCODING as the default encoding for future ports. */
|
||||||
void
|
void
|
||||||
scm_i_set_default_port_encoding (const char *encoding)
|
scm_i_set_default_port_encoding (const char *encoding)
|
||||||
{
|
{
|
||||||
if (!scm_port_encoding_init
|
|
||||||
|| !scm_is_fluid (SCM_VARIABLE_REF (default_port_encoding_var)))
|
|
||||||
scm_misc_error (NULL, "tried to set port encoding fluid before it is initialized",
|
|
||||||
SCM_EOL);
|
|
||||||
|
|
||||||
if (encoding_matches (encoding, "ISO-8859-1"))
|
if (encoding_matches (encoding, "ISO-8859-1"))
|
||||||
scm_fluid_set_x (SCM_VARIABLE_REF (default_port_encoding_var), SCM_BOOL_F);
|
scm_fluid_set_x (SCM_VARIABLE_REF (default_port_encoding_var), SCM_BOOL_F);
|
||||||
else
|
else
|
||||||
|
@ -940,63 +922,41 @@ scm_i_set_default_port_encoding (const char *encoding)
|
||||||
const char *
|
const char *
|
||||||
scm_i_default_port_encoding (void)
|
scm_i_default_port_encoding (void)
|
||||||
{
|
{
|
||||||
if (!scm_port_encoding_init)
|
SCM encoding;
|
||||||
return "ISO-8859-1";
|
|
||||||
else if (!scm_is_fluid (SCM_VARIABLE_REF (default_port_encoding_var)))
|
encoding = scm_fluid_ref (SCM_VARIABLE_REF (default_port_encoding_var));
|
||||||
|
if (!scm_is_string (encoding))
|
||||||
return "ISO-8859-1";
|
return "ISO-8859-1";
|
||||||
else
|
else
|
||||||
{
|
return scm_i_string_chars (encoding);
|
||||||
SCM encoding;
|
|
||||||
|
|
||||||
encoding = scm_fluid_ref (SCM_VARIABLE_REF (default_port_encoding_var));
|
|
||||||
if (!scm_is_string (encoding))
|
|
||||||
return "ISO-8859-1";
|
|
||||||
else
|
|
||||||
return scm_i_string_chars (encoding);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* A fluid specifying the default conversion handler for newly created
|
/* A fluid specifying the default conversion handler for newly created
|
||||||
ports. Its value should be one of the symbols below. */
|
ports. Its value should be one of the symbols below. */
|
||||||
SCM_VARIABLE (default_conversion_strategy_var,
|
static SCM 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. */
|
/* The possible conversion strategies. */
|
||||||
SCM_SYMBOL (sym_error, "error");
|
static SCM sym_error;
|
||||||
SCM_SYMBOL (sym_substitute, "substitute");
|
static SCM sym_substitute;
|
||||||
SCM_SYMBOL (sym_escape, "escape");
|
static SCM sym_escape;
|
||||||
|
|
||||||
/* Return the default failed encoding conversion policy for new created
|
/* Return the default failed encoding conversion policy for new created
|
||||||
ports. */
|
ports. */
|
||||||
scm_t_string_failed_conversion_handler
|
scm_t_string_failed_conversion_handler
|
||||||
scm_i_default_port_conversion_handler (void)
|
scm_i_default_port_conversion_handler (void)
|
||||||
{
|
{
|
||||||
scm_t_string_failed_conversion_handler handler;
|
SCM value;
|
||||||
|
|
||||||
if (!scm_conversion_strategy_init
|
value = scm_fluid_ref (SCM_VARIABLE_REF (default_conversion_strategy_var));
|
||||||
|| !scm_is_fluid (SCM_VARIABLE_REF (default_conversion_strategy_var)))
|
|
||||||
handler = SCM_FAILED_CONVERSION_QUESTION_MARK;
|
if (scm_is_eq (sym_substitute, value))
|
||||||
|
return SCM_FAILED_CONVERSION_QUESTION_MARK;
|
||||||
|
else if (scm_is_eq (sym_escape, value))
|
||||||
|
return SCM_FAILED_CONVERSION_ESCAPE_SEQUENCE;
|
||||||
else
|
else
|
||||||
{
|
/* Default to 'error also when the fluid's value is not one of
|
||||||
SCM fluid, value;
|
the valid symbols. */
|
||||||
|
return SCM_FAILED_CONVERSION_ERROR;
|
||||||
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. */
|
/* Use HANDLER as the default conversion strategy for future ports. */
|
||||||
|
@ -1006,11 +966,6 @@ scm_i_set_default_port_conversion_handler (scm_t_string_failed_conversion_handle
|
||||||
{
|
{
|
||||||
SCM strategy;
|
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)
|
switch (handler)
|
||||||
{
|
{
|
||||||
case SCM_FAILED_CONVERSION_ERROR:
|
case SCM_FAILED_CONVERSION_ERROR:
|
||||||
|
@ -3286,36 +3241,16 @@ SCM_DEFINE (scm_sys_make_void_port, "%make-void-port", 1, 0, 0,
|
||||||
|
|
||||||
/* Initialization. */
|
/* Initialization. */
|
||||||
|
|
||||||
void
|
static void
|
||||||
scm_init_ports ()
|
scm_init_ice_9_ports (void)
|
||||||
{
|
{
|
||||||
|
#include "libguile/ports.x"
|
||||||
|
|
||||||
/* lseek() symbols. */
|
/* lseek() symbols. */
|
||||||
scm_c_define ("SEEK_SET", scm_from_int (SEEK_SET));
|
scm_c_define ("SEEK_SET", scm_from_int (SEEK_SET));
|
||||||
scm_c_define ("SEEK_CUR", scm_from_int (SEEK_CUR));
|
scm_c_define ("SEEK_CUR", scm_from_int (SEEK_CUR));
|
||||||
scm_c_define ("SEEK_END", scm_from_int (SEEK_END));
|
scm_c_define ("SEEK_END", scm_from_int (SEEK_END));
|
||||||
|
|
||||||
scm_tc16_void_port = scm_make_port_type ("void", void_port_read,
|
|
||||||
void_port_write);
|
|
||||||
|
|
||||||
cur_inport_fluid = scm_make_fluid ();
|
|
||||||
cur_outport_fluid = scm_make_fluid ();
|
|
||||||
cur_errport_fluid = scm_make_fluid ();
|
|
||||||
cur_warnport_fluid = scm_make_fluid ();
|
|
||||||
cur_loadport_fluid = scm_make_fluid ();
|
|
||||||
|
|
||||||
scm_i_port_weak_set = scm_c_make_weak_set (31);
|
|
||||||
|
|
||||||
#include "libguile/ports.x"
|
|
||||||
|
|
||||||
/* Use Latin-1 as the default port encoding. */
|
|
||||||
SCM_VARIABLE_SET (default_port_encoding_var,
|
|
||||||
scm_make_fluid_with_default (SCM_BOOL_F));
|
|
||||||
scm_port_encoding_init = 1;
|
|
||||||
|
|
||||||
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
|
/* These bindings are used when boot-9 turns `current-input-port' et
|
||||||
al into parameters. They are then removed from the guile module. */
|
al into parameters. They are then removed from the guile module. */
|
||||||
scm_c_define ("%current-input-port-fluid", cur_inport_fluid);
|
scm_c_define ("%current-input-port-fluid", cur_inport_fluid);
|
||||||
|
@ -3324,6 +3259,61 @@ scm_init_ports ()
|
||||||
scm_c_define ("%current-warning-port-fluid", cur_warnport_fluid);
|
scm_c_define ("%current-warning-port-fluid", cur_warnport_fluid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
scm_init_ports (void)
|
||||||
|
{
|
||||||
|
scm_tc16_void_port = scm_make_port_type ("void", void_port_read,
|
||||||
|
void_port_write);
|
||||||
|
|
||||||
|
scm_i_port_weak_set = scm_c_make_weak_set (31);
|
||||||
|
|
||||||
|
cur_inport_fluid = scm_make_fluid ();
|
||||||
|
cur_outport_fluid = scm_make_fluid ();
|
||||||
|
cur_errport_fluid = scm_make_fluid ();
|
||||||
|
cur_warnport_fluid = scm_make_fluid ();
|
||||||
|
cur_loadport_fluid = scm_make_fluid ();
|
||||||
|
|
||||||
|
sym_substitute = scm_from_latin1_symbol ("substitute");
|
||||||
|
sym_escape = scm_from_latin1_symbol ("escape");
|
||||||
|
sym_error = scm_from_latin1_symbol ("error");
|
||||||
|
|
||||||
|
/* Use Latin-1 as the default port encoding. */
|
||||||
|
default_port_encoding_var =
|
||||||
|
scm_c_define ("%default-port-encoding",
|
||||||
|
scm_make_fluid_with_default (SCM_BOOL_F));
|
||||||
|
default_conversion_strategy_var =
|
||||||
|
scm_c_define ("%default-port-conversion-strategy",
|
||||||
|
scm_make_fluid_with_default (sym_substitute));
|
||||||
|
|
||||||
|
scm_c_register_extension ("libguile-" SCM_EFFECTIVE_VERSION,
|
||||||
|
"scm_init_ice_9_ports",
|
||||||
|
(scm_t_extension_init_func) scm_init_ice_9_ports,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
/* The following bindings are used early in boot-9.scm. */
|
||||||
|
|
||||||
|
/* Used by `include'. */
|
||||||
|
scm_c_define_gsubr (s_scm_set_port_encoding_x, 2, 0, 0,
|
||||||
|
(scm_t_subr) scm_set_port_encoding_x);
|
||||||
|
scm_c_define_gsubr (s_scm_eof_object_p, 1, 0, 0,
|
||||||
|
(scm_t_subr) scm_eof_object_p);
|
||||||
|
|
||||||
|
/* Used by a number of error/warning-printing routines. */
|
||||||
|
scm_c_define_gsubr (s_scm_force_output, 0, 1, 0,
|
||||||
|
(scm_t_subr) scm_force_output);
|
||||||
|
|
||||||
|
/* Used by `file-exists?' and related functions if `stat' is
|
||||||
|
unavailable. */
|
||||||
|
scm_c_define_gsubr (s_scm_close_port, 1, 0, 0,
|
||||||
|
(scm_t_subr) scm_close_port);
|
||||||
|
|
||||||
|
/* Used by error routines. */
|
||||||
|
scm_c_define_gsubr (s_scm_current_error_port, 0, 0, 0,
|
||||||
|
(scm_t_subr) scm_current_error_port);
|
||||||
|
scm_c_define_gsubr (s_scm_current_warning_port, 0, 0, 0,
|
||||||
|
(scm_t_subr) scm_current_warning_port);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Local Variables:
|
Local Variables:
|
||||||
c-file-style: "gnu"
|
c-file-style: "gnu"
|
||||||
|
|
|
@ -88,6 +88,7 @@ SOURCES = \
|
||||||
ice-9/poe.scm \
|
ice-9/poe.scm \
|
||||||
ice-9/poll.scm \
|
ice-9/poll.scm \
|
||||||
ice-9/popen.scm \
|
ice-9/popen.scm \
|
||||||
|
ice-9/ports.scm \
|
||||||
ice-9/posix.scm \
|
ice-9/posix.scm \
|
||||||
ice-9/pretty-print.scm \
|
ice-9/pretty-print.scm \
|
||||||
ice-9/psyntax-pp.scm \
|
ice-9/psyntax-pp.scm \
|
||||||
|
|
|
@ -151,38 +151,6 @@ a-cont
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
;;; {Low-Level Port Code}
|
|
||||||
;;;
|
|
||||||
|
|
||||||
;; These are used to request the proper mode to open files in.
|
|
||||||
;;
|
|
||||||
(define OPEN_READ "r")
|
|
||||||
(define OPEN_WRITE "w")
|
|
||||||
(define OPEN_BOTH "r+")
|
|
||||||
|
|
||||||
(define *null-device* "/dev/null")
|
|
||||||
|
|
||||||
;; NOTE: Later in this file, this is redefined to support keywords
|
|
||||||
(define (open-input-file str)
|
|
||||||
"Takes a string naming an existing file and returns an input port
|
|
||||||
capable of delivering characters from the file. If the file
|
|
||||||
cannot be opened, an error is signalled."
|
|
||||||
(open-file str OPEN_READ))
|
|
||||||
|
|
||||||
;; NOTE: Later in this file, this is redefined to support keywords
|
|
||||||
(define (open-output-file str)
|
|
||||||
"Takes a string naming an output file to be created and returns an
|
|
||||||
output port capable of writing characters to a new file by that
|
|
||||||
name. If the file cannot be opened, an error is signalled. If a
|
|
||||||
file with the given name already exists, the effect is unspecified."
|
|
||||||
(open-file str OPEN_WRITE))
|
|
||||||
|
|
||||||
(define (open-io-file str)
|
|
||||||
"Open file with name STR for both input and output."
|
|
||||||
(open-file str OPEN_BOTH))
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
;;; {Simple Debugging Tools}
|
;;; {Simple Debugging Tools}
|
||||||
;;;
|
;;;
|
||||||
|
|
||||||
|
@ -315,11 +283,10 @@ file with the given name already exists, the effect is unspecified."
|
||||||
(for-eachn (cdr l1) (map cdr rest))))))))
|
(for-eachn (cdr l1) (map cdr rest))))))))
|
||||||
|
|
||||||
|
|
||||||
;; Temporary definition used in the include-from-path expansion;
|
;; Temporary definitions used by `include'; replaced later.
|
||||||
;; replaced later.
|
|
||||||
|
|
||||||
(define (absolute-file-name? file-name)
|
(define (absolute-file-name? file-name) #t)
|
||||||
#t)
|
(define (open-input-file str) (open-file str "r"))
|
||||||
|
|
||||||
;;; {and-map and or-map}
|
;;; {and-map and or-map}
|
||||||
;;;
|
;;;
|
||||||
|
@ -1195,11 +1162,6 @@ VALUE."
|
||||||
;;
|
;;
|
||||||
;; It should print OBJECT to PORT.
|
;; It should print OBJECT to PORT.
|
||||||
|
|
||||||
(define (inherit-print-state old-port new-port)
|
|
||||||
(if (get-print-state old-port)
|
|
||||||
(port-with-print-state new-port (get-print-state old-port))
|
|
||||||
new-port))
|
|
||||||
|
|
||||||
;; 0: type-name, 1: fields, 2: constructor
|
;; 0: type-name, 1: fields, 2: constructor
|
||||||
(define record-type-vtable
|
(define record-type-vtable
|
||||||
(let ((s (make-vtable (string-append standard-vtable-fields "prprpw")
|
(let ((s (make-vtable (string-append standard-vtable-fields "prprpw")
|
||||||
|
@ -1446,29 +1408,6 @@ CONV is not applied to the initial value."
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
;;; Current ports as parameters.
|
|
||||||
;;;
|
|
||||||
|
|
||||||
(let ()
|
|
||||||
(define-syntax-rule (port-parameterize! binding fluid predicate msg)
|
|
||||||
(begin
|
|
||||||
(set! binding (fluid->parameter (module-ref (current-module) 'fluid)
|
|
||||||
(lambda (x)
|
|
||||||
(if (predicate x) x
|
|
||||||
(error msg x)))))
|
|
||||||
(hashq-remove! (%get-pre-modules-obarray) 'fluid)))
|
|
||||||
|
|
||||||
(port-parameterize! current-input-port %current-input-port-fluid
|
|
||||||
input-port? "expected an input port")
|
|
||||||
(port-parameterize! current-output-port %current-output-port-fluid
|
|
||||||
output-port? "expected an output port")
|
|
||||||
(port-parameterize! current-error-port %current-error-port-fluid
|
|
||||||
output-port? "expected an output port")
|
|
||||||
(port-parameterize! current-warning-port %current-warning-port-fluid
|
|
||||||
output-port? "expected an output port"))
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
;;; {Languages}
|
;;; {Languages}
|
||||||
;;;
|
;;;
|
||||||
|
|
||||||
|
@ -1483,140 +1422,6 @@ CONV is not applied to the initial value."
|
||||||
;;; {High-Level Port Routines}
|
;;; {High-Level Port Routines}
|
||||||
;;;
|
;;;
|
||||||
|
|
||||||
(define* (open-input-file
|
|
||||||
file #:key (binary #f) (encoding #f) (guess-encoding #f))
|
|
||||||
"Takes a string naming an existing file and returns an input port
|
|
||||||
capable of delivering characters from the file. If the file
|
|
||||||
cannot be opened, an error is signalled."
|
|
||||||
(open-file file (if binary "rb" "r")
|
|
||||||
#:encoding encoding
|
|
||||||
#:guess-encoding guess-encoding))
|
|
||||||
|
|
||||||
(define* (open-output-file file #:key (binary #f) (encoding #f))
|
|
||||||
"Takes a string naming an output file to be created and returns an
|
|
||||||
output port capable of writing characters to a new file by that
|
|
||||||
name. If the file cannot be opened, an error is signalled. If a
|
|
||||||
file with the given name already exists, the effect is unspecified."
|
|
||||||
(open-file file (if binary "wb" "w")
|
|
||||||
#:encoding encoding))
|
|
||||||
|
|
||||||
(define* (call-with-input-file
|
|
||||||
file proc #:key (binary #f) (encoding #f) (guess-encoding #f))
|
|
||||||
"PROC should be a procedure of one argument, and FILE should be a
|
|
||||||
string naming a file. The file must
|
|
||||||
already exist. These procedures call PROC
|
|
||||||
with one argument: the port obtained by opening the named file for
|
|
||||||
input or output. If the file cannot be opened, an error is
|
|
||||||
signalled. If the procedure returns, then the port is closed
|
|
||||||
automatically and the values yielded by the procedure are returned.
|
|
||||||
If the procedure does not return, then the port will not be closed
|
|
||||||
automatically unless it is possible to prove that the port will
|
|
||||||
never again be used for a read or write operation."
|
|
||||||
(let ((p (open-input-file file
|
|
||||||
#:binary binary
|
|
||||||
#:encoding encoding
|
|
||||||
#:guess-encoding guess-encoding)))
|
|
||||||
(call-with-values
|
|
||||||
(lambda () (proc p))
|
|
||||||
(lambda vals
|
|
||||||
(close-input-port p)
|
|
||||||
(apply values vals)))))
|
|
||||||
|
|
||||||
(define* (call-with-output-file file proc #:key (binary #f) (encoding #f))
|
|
||||||
"PROC should be a procedure of one argument, and FILE should be a
|
|
||||||
string naming a file. The behaviour is unspecified if the file
|
|
||||||
already exists. These procedures call PROC
|
|
||||||
with one argument: the port obtained by opening the named file for
|
|
||||||
input or output. If the file cannot be opened, an error is
|
|
||||||
signalled. If the procedure returns, then the port is closed
|
|
||||||
automatically and the values yielded by the procedure are returned.
|
|
||||||
If the procedure does not return, then the port will not be closed
|
|
||||||
automatically unless it is possible to prove that the port will
|
|
||||||
never again be used for a read or write operation."
|
|
||||||
(let ((p (open-output-file file #:binary binary #:encoding encoding)))
|
|
||||||
(call-with-values
|
|
||||||
(lambda () (proc p))
|
|
||||||
(lambda vals
|
|
||||||
(close-output-port p)
|
|
||||||
(apply values vals)))))
|
|
||||||
|
|
||||||
(define (with-input-from-port port thunk)
|
|
||||||
(parameterize ((current-input-port port))
|
|
||||||
(thunk)))
|
|
||||||
|
|
||||||
(define (with-output-to-port port thunk)
|
|
||||||
(parameterize ((current-output-port port))
|
|
||||||
(thunk)))
|
|
||||||
|
|
||||||
(define (with-error-to-port port thunk)
|
|
||||||
(parameterize ((current-error-port port))
|
|
||||||
(thunk)))
|
|
||||||
|
|
||||||
(define* (with-input-from-file
|
|
||||||
file thunk #:key (binary #f) (encoding #f) (guess-encoding #f))
|
|
||||||
"THUNK must be a procedure of no arguments, and FILE must be a
|
|
||||||
string naming a file. The file must already exist. The file is opened for
|
|
||||||
input, an input port connected to it is made
|
|
||||||
the default value returned by `current-input-port',
|
|
||||||
and the THUNK is called with no arguments.
|
|
||||||
When the THUNK returns, the port is closed and the previous
|
|
||||||
default is restored. Returns the values yielded by THUNK. If an
|
|
||||||
escape procedure is used to escape from the continuation of these
|
|
||||||
procedures, their behavior is implementation dependent."
|
|
||||||
(call-with-input-file file
|
|
||||||
(lambda (p) (with-input-from-port p thunk))
|
|
||||||
#:binary binary
|
|
||||||
#:encoding encoding
|
|
||||||
#:guess-encoding guess-encoding))
|
|
||||||
|
|
||||||
(define* (with-output-to-file file thunk #:key (binary #f) (encoding #f))
|
|
||||||
"THUNK must be a procedure of no arguments, and FILE must be a
|
|
||||||
string naming a file. The effect is unspecified if the file already exists.
|
|
||||||
The file is opened for output, an output port connected to it is made
|
|
||||||
the default value returned by `current-output-port',
|
|
||||||
and the THUNK is called with no arguments.
|
|
||||||
When the THUNK returns, the port is closed and the previous
|
|
||||||
default is restored. Returns the values yielded by THUNK. If an
|
|
||||||
escape procedure is used to escape from the continuation of these
|
|
||||||
procedures, their behavior is implementation dependent."
|
|
||||||
(call-with-output-file file
|
|
||||||
(lambda (p) (with-output-to-port p thunk))
|
|
||||||
#:binary binary
|
|
||||||
#:encoding encoding))
|
|
||||||
|
|
||||||
(define* (with-error-to-file file thunk #:key (binary #f) (encoding #f))
|
|
||||||
"THUNK must be a procedure of no arguments, and FILE must be a
|
|
||||||
string naming a file. The effect is unspecified if the file already exists.
|
|
||||||
The file is opened for output, an output port connected to it is made
|
|
||||||
the default value returned by `current-error-port',
|
|
||||||
and the THUNK is called with no arguments.
|
|
||||||
When the THUNK returns, the port is closed and the previous
|
|
||||||
default is restored. Returns the values yielded by THUNK. If an
|
|
||||||
escape procedure is used to escape from the continuation of these
|
|
||||||
procedures, their behavior is implementation dependent."
|
|
||||||
(call-with-output-file file
|
|
||||||
(lambda (p) (with-error-to-port p thunk))
|
|
||||||
#:binary binary
|
|
||||||
#:encoding encoding))
|
|
||||||
|
|
||||||
(define (call-with-input-string string proc)
|
|
||||||
"Calls the one-argument procedure @var{proc} with a newly created
|
|
||||||
input port from which @var{string}'s contents may be read. The value
|
|
||||||
yielded by the @var{proc} is returned."
|
|
||||||
(proc (open-input-string string)))
|
|
||||||
|
|
||||||
(define (with-input-from-string string thunk)
|
|
||||||
"THUNK must be a procedure of no arguments.
|
|
||||||
The test of STRING is opened for
|
|
||||||
input, an input port connected to it is made,
|
|
||||||
and the THUNK is called with no arguments.
|
|
||||||
When the THUNK returns, the port is closed.
|
|
||||||
Returns the values yielded by THUNK. If an
|
|
||||||
escape procedure is used to escape from the continuation of these
|
|
||||||
procedures, their behavior is implementation dependent."
|
|
||||||
(call-with-input-string string
|
|
||||||
(lambda (p) (with-input-from-port p thunk))))
|
|
||||||
|
|
||||||
(define (call-with-output-string proc)
|
(define (call-with-output-string proc)
|
||||||
"Calls the one-argument procedure @var{proc} with a newly created output
|
"Calls the one-argument procedure @var{proc} with a newly created output
|
||||||
port. When the function returns, the string composed of the characters
|
port. When the function returns, the string composed of the characters
|
||||||
|
@ -1625,18 +1430,6 @@ written into the port is returned."
|
||||||
(proc port)
|
(proc port)
|
||||||
(get-output-string port)))
|
(get-output-string port)))
|
||||||
|
|
||||||
(define (with-output-to-string thunk)
|
|
||||||
"Calls THUNK and returns its output as a string."
|
|
||||||
(call-with-output-string
|
|
||||||
(lambda (p) (with-output-to-port p thunk))))
|
|
||||||
|
|
||||||
(define (with-error-to-string thunk)
|
|
||||||
"Calls THUNK and returns its error output as a string."
|
|
||||||
(call-with-output-string
|
|
||||||
(lambda (p) (with-error-to-port p thunk))))
|
|
||||||
|
|
||||||
(define the-eof-object (call-with-input-string "" (lambda (p) (read-char p))))
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
;;; {Booleans}
|
;;; {Booleans}
|
||||||
|
@ -1758,95 +1551,9 @@ written into the port is returned."
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
;;; {File Descriptors and Ports}
|
;;; {C Environment}
|
||||||
;;;
|
;;;
|
||||||
|
|
||||||
(define file-position ftell)
|
|
||||||
(define* (file-set-position port offset #:optional (whence SEEK_SET))
|
|
||||||
(seek port offset whence))
|
|
||||||
|
|
||||||
(define (move->fdes fd/port fd)
|
|
||||||
(cond ((integer? fd/port)
|
|
||||||
(dup->fdes fd/port fd)
|
|
||||||
(close fd/port)
|
|
||||||
fd)
|
|
||||||
(else
|
|
||||||
(primitive-move->fdes fd/port fd)
|
|
||||||
(set-port-revealed! fd/port 1)
|
|
||||||
fd/port)))
|
|
||||||
|
|
||||||
(define (release-port-handle port)
|
|
||||||
(let ((revealed (port-revealed port)))
|
|
||||||
(if (> revealed 0)
|
|
||||||
(set-port-revealed! port (- revealed 1)))))
|
|
||||||
|
|
||||||
(define dup->port
|
|
||||||
(case-lambda
|
|
||||||
((port/fd mode)
|
|
||||||
(fdopen (dup->fdes port/fd) mode))
|
|
||||||
((port/fd mode new-fd)
|
|
||||||
(let ((port (fdopen (dup->fdes port/fd new-fd) mode)))
|
|
||||||
(set-port-revealed! port 1)
|
|
||||||
port))))
|
|
||||||
|
|
||||||
(define dup->inport
|
|
||||||
(case-lambda
|
|
||||||
((port/fd)
|
|
||||||
(dup->port port/fd "r"))
|
|
||||||
((port/fd new-fd)
|
|
||||||
(dup->port port/fd "r" new-fd))))
|
|
||||||
|
|
||||||
(define dup->outport
|
|
||||||
(case-lambda
|
|
||||||
((port/fd)
|
|
||||||
(dup->port port/fd "w"))
|
|
||||||
((port/fd new-fd)
|
|
||||||
(dup->port port/fd "w" new-fd))))
|
|
||||||
|
|
||||||
(define dup
|
|
||||||
(case-lambda
|
|
||||||
((port/fd)
|
|
||||||
(if (integer? port/fd)
|
|
||||||
(dup->fdes port/fd)
|
|
||||||
(dup->port port/fd (port-mode port/fd))))
|
|
||||||
((port/fd new-fd)
|
|
||||||
(if (integer? port/fd)
|
|
||||||
(dup->fdes port/fd new-fd)
|
|
||||||
(dup->port port/fd (port-mode port/fd) new-fd)))))
|
|
||||||
|
|
||||||
(define (duplicate-port port modes)
|
|
||||||
(dup->port port modes))
|
|
||||||
|
|
||||||
(define (fdes->inport fdes)
|
|
||||||
(let loop ((rest-ports (fdes->ports fdes)))
|
|
||||||
(cond ((null? rest-ports)
|
|
||||||
(let ((result (fdopen fdes "r")))
|
|
||||||
(set-port-revealed! result 1)
|
|
||||||
result))
|
|
||||||
((input-port? (car rest-ports))
|
|
||||||
(set-port-revealed! (car rest-ports)
|
|
||||||
(+ (port-revealed (car rest-ports)) 1))
|
|
||||||
(car rest-ports))
|
|
||||||
(else
|
|
||||||
(loop (cdr rest-ports))))))
|
|
||||||
|
|
||||||
(define (fdes->outport fdes)
|
|
||||||
(let loop ((rest-ports (fdes->ports fdes)))
|
|
||||||
(cond ((null? rest-ports)
|
|
||||||
(let ((result (fdopen fdes "w")))
|
|
||||||
(set-port-revealed! result 1)
|
|
||||||
result))
|
|
||||||
((output-port? (car rest-ports))
|
|
||||||
(set-port-revealed! (car rest-ports)
|
|
||||||
(+ (port-revealed (car rest-ports)) 1))
|
|
||||||
(car rest-ports))
|
|
||||||
(else
|
|
||||||
(loop (cdr rest-ports))))))
|
|
||||||
|
|
||||||
(define (port->fdes port)
|
|
||||||
(set-port-revealed! port (+ (port-revealed port) 1))
|
|
||||||
(fileno port))
|
|
||||||
|
|
||||||
(define (setenv name value)
|
(define (setenv name value)
|
||||||
(if value
|
(if value
|
||||||
(putenv (string-append name "=" value))
|
(putenv (string-append name "=" value))
|
||||||
|
@ -4322,6 +4029,16 @@ when none is available, reading FILE-NAME with READER."
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
;;; {Ports}
|
||||||
|
;;;
|
||||||
|
|
||||||
|
;; Allow code in (guile) to use port bindings.
|
||||||
|
(module-use! the-root-module (resolve-interface '(ice-9 ports)))
|
||||||
|
;; Allow users of (guile) to see port bindings.
|
||||||
|
(module-use! the-scm-module (resolve-interface '(ice-9 ports)))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
;;; SRFI-4 in the default environment. FIXME: we should figure out how
|
;;; SRFI-4 in the default environment. FIXME: we should figure out how
|
||||||
;;; to deprecate this.
|
;;; to deprecate this.
|
||||||
;;;
|
;;;
|
||||||
|
|
469
module/ice-9/ports.scm
Normal file
469
module/ice-9/ports.scm
Normal file
|
@ -0,0 +1,469 @@
|
||||||
|
;;; Ports
|
||||||
|
;;; Copyright (C) 2016 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 the
|
||||||
|
;;; License, or (at your option) any later version.
|
||||||
|
;;;
|
||||||
|
;;; This library is distributed in the hope that it will be useful, but
|
||||||
|
;;; WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
;;; Lesser General Public License for more details.
|
||||||
|
;;;
|
||||||
|
;;; You should have received a copy of the GNU Lesser General Public
|
||||||
|
;;; License along with this program. If not, see
|
||||||
|
;;; <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
;;; Commentary:
|
||||||
|
;;;
|
||||||
|
;;; Implementation of input/output routines over ports.
|
||||||
|
;;;
|
||||||
|
;;; Note that loading this module overrides some core bindings; see the
|
||||||
|
;;; `replace-bootstrap-bindings' invocation below for details.
|
||||||
|
;;;
|
||||||
|
;;; Code:
|
||||||
|
|
||||||
|
|
||||||
|
(define-module (ice-9 ports)
|
||||||
|
#:export (;; Definitions from ports.c.
|
||||||
|
%port-property
|
||||||
|
%set-port-property!
|
||||||
|
current-input-port current-output-port
|
||||||
|
current-error-port current-warning-port
|
||||||
|
set-current-input-port set-current-output-port
|
||||||
|
set-current-error-port
|
||||||
|
port-mode
|
||||||
|
port?
|
||||||
|
input-port?
|
||||||
|
output-port?
|
||||||
|
port-closed?
|
||||||
|
eof-object?
|
||||||
|
close-port
|
||||||
|
close-input-port
|
||||||
|
close-output-port
|
||||||
|
;; These two are currently defined by scm_init_ports; fix?
|
||||||
|
;; %default-port-encoding
|
||||||
|
;; %default-port-conversion-strategy
|
||||||
|
port-encoding
|
||||||
|
set-port-encoding!
|
||||||
|
port-conversion-strategy
|
||||||
|
set-port-conversion-strategy!
|
||||||
|
read-char
|
||||||
|
peek-char
|
||||||
|
unread-char
|
||||||
|
unread-string
|
||||||
|
setvbuf
|
||||||
|
drain-input
|
||||||
|
force-output
|
||||||
|
char-ready?
|
||||||
|
seek SEEK_SET SEEK_CUR SEEK_END
|
||||||
|
truncate-file
|
||||||
|
port-line
|
||||||
|
set-port-line!
|
||||||
|
port-column
|
||||||
|
set-port-column!
|
||||||
|
port-filename
|
||||||
|
set-port-filename!
|
||||||
|
port-for-each
|
||||||
|
flush-all-ports
|
||||||
|
%make-void-port
|
||||||
|
|
||||||
|
;; Definitions from fports.c.
|
||||||
|
open-file
|
||||||
|
file-port?
|
||||||
|
port-revealed
|
||||||
|
set-port-revealed!
|
||||||
|
adjust-port-revealed!
|
||||||
|
;; note: %file-port-name-canonicalization is used in boot-9
|
||||||
|
|
||||||
|
;; Definitions from ioext.c.
|
||||||
|
ftell
|
||||||
|
redirect-port
|
||||||
|
dup->fdes
|
||||||
|
dup2
|
||||||
|
fileno
|
||||||
|
isatty?
|
||||||
|
fdopen
|
||||||
|
primitive-move->fdes
|
||||||
|
fdes->ports
|
||||||
|
|
||||||
|
;; Definitions in Scheme
|
||||||
|
file-position
|
||||||
|
file-set-position
|
||||||
|
move->fdes
|
||||||
|
release-port-handle
|
||||||
|
dup->port
|
||||||
|
dup->inport
|
||||||
|
dup->outport
|
||||||
|
dup
|
||||||
|
duplicate-port
|
||||||
|
fdes->inport
|
||||||
|
fdes->outport
|
||||||
|
port->fdes
|
||||||
|
OPEN_READ OPEN_WRITE OPEN_BOTH
|
||||||
|
*null-device*
|
||||||
|
open-input-file
|
||||||
|
open-output-file
|
||||||
|
open-io-file
|
||||||
|
call-with-input-file
|
||||||
|
call-with-output-file
|
||||||
|
with-input-from-port
|
||||||
|
with-output-to-port
|
||||||
|
with-error-to-port
|
||||||
|
with-input-from-file
|
||||||
|
with-output-to-file
|
||||||
|
with-error-to-file
|
||||||
|
call-with-input-string
|
||||||
|
with-input-from-string
|
||||||
|
call-with-output-string
|
||||||
|
with-output-to-string
|
||||||
|
with-error-to-string
|
||||||
|
the-eof-object
|
||||||
|
inherit-print-state))
|
||||||
|
|
||||||
|
(define (replace-bootstrap-bindings syms)
|
||||||
|
(for-each
|
||||||
|
(lambda (sym)
|
||||||
|
(let* ((var (module-variable the-scm-module sym))
|
||||||
|
(mod (current-module))
|
||||||
|
(iface (module-public-interface mod)))
|
||||||
|
(unless var (error "unbound in root module" sym))
|
||||||
|
(module-add! mod sym var)
|
||||||
|
(when (module-local-variable iface sym)
|
||||||
|
(module-add! iface sym var))))
|
||||||
|
syms))
|
||||||
|
|
||||||
|
(replace-bootstrap-bindings '(open-file
|
||||||
|
open-input-file
|
||||||
|
set-port-encoding!
|
||||||
|
eof-object?
|
||||||
|
force-output
|
||||||
|
call-with-output-string
|
||||||
|
close-port
|
||||||
|
current-error-port
|
||||||
|
current-warning-port))
|
||||||
|
|
||||||
|
(load-extension (string-append "libguile-" (effective-version))
|
||||||
|
"scm_init_ice_9_ports")
|
||||||
|
(load-extension (string-append "libguile-" (effective-version))
|
||||||
|
"scm_init_ice_9_fports")
|
||||||
|
(load-extension (string-append "libguile-" (effective-version))
|
||||||
|
"scm_init_ice_9_ioext")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
;;; Current ports as parameters.
|
||||||
|
;;;
|
||||||
|
|
||||||
|
(define current-input-port
|
||||||
|
(fluid->parameter %current-input-port-fluid
|
||||||
|
(lambda (x)
|
||||||
|
(unless (input-port? x)
|
||||||
|
(error "expected an input port" x))
|
||||||
|
x)))
|
||||||
|
|
||||||
|
(define current-output-port
|
||||||
|
(fluid->parameter %current-output-port-fluid
|
||||||
|
(lambda (x)
|
||||||
|
(unless (output-port? x)
|
||||||
|
(error "expected an output port" x))
|
||||||
|
x)))
|
||||||
|
|
||||||
|
(define current-error-port
|
||||||
|
(fluid->parameter %current-error-port-fluid
|
||||||
|
(lambda (x)
|
||||||
|
(unless (output-port? x)
|
||||||
|
(error "expected an output port" x))
|
||||||
|
x)))
|
||||||
|
|
||||||
|
(define current-warning-port
|
||||||
|
(fluid->parameter %current-warning-port-fluid
|
||||||
|
(lambda (x)
|
||||||
|
(unless (output-port? x)
|
||||||
|
(error "expected an output port" x))
|
||||||
|
x)))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
;;; {File Descriptors and Ports}
|
||||||
|
;;;
|
||||||
|
|
||||||
|
(define file-position ftell)
|
||||||
|
(define* (file-set-position port offset #:optional (whence SEEK_SET))
|
||||||
|
(seek port offset whence))
|
||||||
|
|
||||||
|
(define (move->fdes fd/port fd)
|
||||||
|
(cond ((integer? fd/port)
|
||||||
|
(dup->fdes fd/port fd)
|
||||||
|
(close fd/port)
|
||||||
|
fd)
|
||||||
|
(else
|
||||||
|
(primitive-move->fdes fd/port fd)
|
||||||
|
(set-port-revealed! fd/port 1)
|
||||||
|
fd/port)))
|
||||||
|
|
||||||
|
(define (release-port-handle port)
|
||||||
|
(let ((revealed (port-revealed port)))
|
||||||
|
(if (> revealed 0)
|
||||||
|
(set-port-revealed! port (- revealed 1)))))
|
||||||
|
|
||||||
|
(define dup->port
|
||||||
|
(case-lambda
|
||||||
|
((port/fd mode)
|
||||||
|
(fdopen (dup->fdes port/fd) mode))
|
||||||
|
((port/fd mode new-fd)
|
||||||
|
(let ((port (fdopen (dup->fdes port/fd new-fd) mode)))
|
||||||
|
(set-port-revealed! port 1)
|
||||||
|
port))))
|
||||||
|
|
||||||
|
(define dup->inport
|
||||||
|
(case-lambda
|
||||||
|
((port/fd)
|
||||||
|
(dup->port port/fd "r"))
|
||||||
|
((port/fd new-fd)
|
||||||
|
(dup->port port/fd "r" new-fd))))
|
||||||
|
|
||||||
|
(define dup->outport
|
||||||
|
(case-lambda
|
||||||
|
((port/fd)
|
||||||
|
(dup->port port/fd "w"))
|
||||||
|
((port/fd new-fd)
|
||||||
|
(dup->port port/fd "w" new-fd))))
|
||||||
|
|
||||||
|
(define dup
|
||||||
|
(case-lambda
|
||||||
|
((port/fd)
|
||||||
|
(if (integer? port/fd)
|
||||||
|
(dup->fdes port/fd)
|
||||||
|
(dup->port port/fd (port-mode port/fd))))
|
||||||
|
((port/fd new-fd)
|
||||||
|
(if (integer? port/fd)
|
||||||
|
(dup->fdes port/fd new-fd)
|
||||||
|
(dup->port port/fd (port-mode port/fd) new-fd)))))
|
||||||
|
|
||||||
|
(define (duplicate-port port modes)
|
||||||
|
(dup->port port modes))
|
||||||
|
|
||||||
|
(define (fdes->inport fdes)
|
||||||
|
(let loop ((rest-ports (fdes->ports fdes)))
|
||||||
|
(cond ((null? rest-ports)
|
||||||
|
(let ((result (fdopen fdes "r")))
|
||||||
|
(set-port-revealed! result 1)
|
||||||
|
result))
|
||||||
|
((input-port? (car rest-ports))
|
||||||
|
(set-port-revealed! (car rest-ports)
|
||||||
|
(+ (port-revealed (car rest-ports)) 1))
|
||||||
|
(car rest-ports))
|
||||||
|
(else
|
||||||
|
(loop (cdr rest-ports))))))
|
||||||
|
|
||||||
|
(define (fdes->outport fdes)
|
||||||
|
(let loop ((rest-ports (fdes->ports fdes)))
|
||||||
|
(cond ((null? rest-ports)
|
||||||
|
(let ((result (fdopen fdes "w")))
|
||||||
|
(set-port-revealed! result 1)
|
||||||
|
result))
|
||||||
|
((output-port? (car rest-ports))
|
||||||
|
(set-port-revealed! (car rest-ports)
|
||||||
|
(+ (port-revealed (car rest-ports)) 1))
|
||||||
|
(car rest-ports))
|
||||||
|
(else
|
||||||
|
(loop (cdr rest-ports))))))
|
||||||
|
|
||||||
|
(define (port->fdes port)
|
||||||
|
(set-port-revealed! port (+ (port-revealed port) 1))
|
||||||
|
(fileno port))
|
||||||
|
|
||||||
|
;; Legacy interfaces.
|
||||||
|
|
||||||
|
(define (set-current-input-port port)
|
||||||
|
"Set the current default input port to @var{port}."
|
||||||
|
(current-input-port port))
|
||||||
|
|
||||||
|
(define (set-current-output-port port)
|
||||||
|
"Set the current default output port to @var{port}."
|
||||||
|
(current-output-port port))
|
||||||
|
|
||||||
|
(define (set-current-error-port port)
|
||||||
|
"Set the current default error port to @var{port}."
|
||||||
|
(current-error-port port))
|
||||||
|
|
||||||
|
|
||||||
|
;;;; high level routines
|
||||||
|
|
||||||
|
|
||||||
|
;;; {High-Level Port Routines}
|
||||||
|
;;;
|
||||||
|
|
||||||
|
;; These are used to request the proper mode to open files in.
|
||||||
|
;;
|
||||||
|
(define OPEN_READ "r")
|
||||||
|
(define OPEN_WRITE "w")
|
||||||
|
(define OPEN_BOTH "r+")
|
||||||
|
|
||||||
|
(define *null-device* "/dev/null")
|
||||||
|
|
||||||
|
(define* (open-input-file
|
||||||
|
file #:key (binary #f) (encoding #f) (guess-encoding #f))
|
||||||
|
"Takes a string naming an existing file and returns an input port
|
||||||
|
capable of delivering characters from the file. If the file
|
||||||
|
cannot be opened, an error is signalled."
|
||||||
|
(open-file file (if binary "rb" "r")
|
||||||
|
#:encoding encoding
|
||||||
|
#:guess-encoding guess-encoding))
|
||||||
|
|
||||||
|
(define* (open-output-file file #:key (binary #f) (encoding #f))
|
||||||
|
"Takes a string naming an output file to be created and returns an
|
||||||
|
output port capable of writing characters to a new file by that
|
||||||
|
name. If the file cannot be opened, an error is signalled. If a
|
||||||
|
file with the given name already exists, the effect is unspecified."
|
||||||
|
(open-file file (if binary "wb" "w")
|
||||||
|
#:encoding encoding))
|
||||||
|
|
||||||
|
(define (open-io-file str)
|
||||||
|
"Open file with name STR for both input and output."
|
||||||
|
(open-file str OPEN_BOTH))
|
||||||
|
|
||||||
|
(define* (call-with-input-file
|
||||||
|
file proc #:key (binary #f) (encoding #f) (guess-encoding #f))
|
||||||
|
"PROC should be a procedure of one argument, and FILE should be a
|
||||||
|
string naming a file. The file must
|
||||||
|
already exist. These procedures call PROC
|
||||||
|
with one argument: the port obtained by opening the named file for
|
||||||
|
input or output. If the file cannot be opened, an error is
|
||||||
|
signalled. If the procedure returns, then the port is closed
|
||||||
|
automatically and the values yielded by the procedure are returned.
|
||||||
|
If the procedure does not return, then the port will not be closed
|
||||||
|
automatically unless it is possible to prove that the port will
|
||||||
|
never again be used for a read or write operation."
|
||||||
|
(let ((p (open-input-file file
|
||||||
|
#:binary binary
|
||||||
|
#:encoding encoding
|
||||||
|
#:guess-encoding guess-encoding)))
|
||||||
|
(call-with-values
|
||||||
|
(lambda () (proc p))
|
||||||
|
(lambda vals
|
||||||
|
(close-input-port p)
|
||||||
|
(apply values vals)))))
|
||||||
|
|
||||||
|
(define* (call-with-output-file file proc #:key (binary #f) (encoding #f))
|
||||||
|
"PROC should be a procedure of one argument, and FILE should be a
|
||||||
|
string naming a file. The behaviour is unspecified if the file
|
||||||
|
already exists. These procedures call PROC
|
||||||
|
with one argument: the port obtained by opening the named file for
|
||||||
|
input or output. If the file cannot be opened, an error is
|
||||||
|
signalled. If the procedure returns, then the port is closed
|
||||||
|
automatically and the values yielded by the procedure are returned.
|
||||||
|
If the procedure does not return, then the port will not be closed
|
||||||
|
automatically unless it is possible to prove that the port will
|
||||||
|
never again be used for a read or write operation."
|
||||||
|
(let ((p (open-output-file file #:binary binary #:encoding encoding)))
|
||||||
|
(call-with-values
|
||||||
|
(lambda () (proc p))
|
||||||
|
(lambda vals
|
||||||
|
(close-output-port p)
|
||||||
|
(apply values vals)))))
|
||||||
|
|
||||||
|
(define (with-input-from-port port thunk)
|
||||||
|
(parameterize ((current-input-port port))
|
||||||
|
(thunk)))
|
||||||
|
|
||||||
|
(define (with-output-to-port port thunk)
|
||||||
|
(parameterize ((current-output-port port))
|
||||||
|
(thunk)))
|
||||||
|
|
||||||
|
(define (with-error-to-port port thunk)
|
||||||
|
(parameterize ((current-error-port port))
|
||||||
|
(thunk)))
|
||||||
|
|
||||||
|
(define* (with-input-from-file
|
||||||
|
file thunk #:key (binary #f) (encoding #f) (guess-encoding #f))
|
||||||
|
"THUNK must be a procedure of no arguments, and FILE must be a
|
||||||
|
string naming a file. The file must already exist. The file is opened for
|
||||||
|
input, an input port connected to it is made
|
||||||
|
the default value returned by `current-input-port',
|
||||||
|
and the THUNK is called with no arguments.
|
||||||
|
When the THUNK returns, the port is closed and the previous
|
||||||
|
default is restored. Returns the values yielded by THUNK. If an
|
||||||
|
escape procedure is used to escape from the continuation of these
|
||||||
|
procedures, their behavior is implementation dependent."
|
||||||
|
(call-with-input-file file
|
||||||
|
(lambda (p) (with-input-from-port p thunk))
|
||||||
|
#:binary binary
|
||||||
|
#:encoding encoding
|
||||||
|
#:guess-encoding guess-encoding))
|
||||||
|
|
||||||
|
(define* (with-output-to-file file thunk #:key (binary #f) (encoding #f))
|
||||||
|
"THUNK must be a procedure of no arguments, and FILE must be a
|
||||||
|
string naming a file. The effect is unspecified if the file already exists.
|
||||||
|
The file is opened for output, an output port connected to it is made
|
||||||
|
the default value returned by `current-output-port',
|
||||||
|
and the THUNK is called with no arguments.
|
||||||
|
When the THUNK returns, the port is closed and the previous
|
||||||
|
default is restored. Returns the values yielded by THUNK. If an
|
||||||
|
escape procedure is used to escape from the continuation of these
|
||||||
|
procedures, their behavior is implementation dependent."
|
||||||
|
(call-with-output-file file
|
||||||
|
(lambda (p) (with-output-to-port p thunk))
|
||||||
|
#:binary binary
|
||||||
|
#:encoding encoding))
|
||||||
|
|
||||||
|
(define* (with-error-to-file file thunk #:key (binary #f) (encoding #f))
|
||||||
|
"THUNK must be a procedure of no arguments, and FILE must be a
|
||||||
|
string naming a file. The effect is unspecified if the file already exists.
|
||||||
|
The file is opened for output, an output port connected to it is made
|
||||||
|
the default value returned by `current-error-port',
|
||||||
|
and the THUNK is called with no arguments.
|
||||||
|
When the THUNK returns, the port is closed and the previous
|
||||||
|
default is restored. Returns the values yielded by THUNK. If an
|
||||||
|
escape procedure is used to escape from the continuation of these
|
||||||
|
procedures, their behavior is implementation dependent."
|
||||||
|
(call-with-output-file file
|
||||||
|
(lambda (p) (with-error-to-port p thunk))
|
||||||
|
#:binary binary
|
||||||
|
#:encoding encoding))
|
||||||
|
|
||||||
|
(define (call-with-input-string string proc)
|
||||||
|
"Calls the one-argument procedure @var{proc} with a newly created
|
||||||
|
input port from which @var{string}'s contents may be read. The value
|
||||||
|
yielded by the @var{proc} is returned."
|
||||||
|
(proc (open-input-string string)))
|
||||||
|
|
||||||
|
(define (with-input-from-string string thunk)
|
||||||
|
"THUNK must be a procedure of no arguments.
|
||||||
|
The test of STRING is opened for
|
||||||
|
input, an input port connected to it is made,
|
||||||
|
and the THUNK is called with no arguments.
|
||||||
|
When the THUNK returns, the port is closed.
|
||||||
|
Returns the values yielded by THUNK. If an
|
||||||
|
escape procedure is used to escape from the continuation of these
|
||||||
|
procedures, their behavior is implementation dependent."
|
||||||
|
(call-with-input-string string
|
||||||
|
(lambda (p) (with-input-from-port p thunk))))
|
||||||
|
|
||||||
|
(define (call-with-output-string proc)
|
||||||
|
"Calls the one-argument procedure @var{proc} with a newly created output
|
||||||
|
port. When the function returns, the string composed of the characters
|
||||||
|
written into the port is returned."
|
||||||
|
(let ((port (open-output-string)))
|
||||||
|
(proc port)
|
||||||
|
(get-output-string port)))
|
||||||
|
|
||||||
|
(define (with-output-to-string thunk)
|
||||||
|
"Calls THUNK and returns its output as a string."
|
||||||
|
(call-with-output-string
|
||||||
|
(lambda (p) (with-output-to-port p thunk))))
|
||||||
|
|
||||||
|
(define (with-error-to-string thunk)
|
||||||
|
"Calls THUNK and returns its error output as a string."
|
||||||
|
(call-with-output-string
|
||||||
|
(lambda (p) (with-error-to-port p thunk))))
|
||||||
|
|
||||||
|
(define the-eof-object (call-with-input-string "" (lambda (p) (read-char p))))
|
||||||
|
|
||||||
|
(define (inherit-print-state old-port new-port)
|
||||||
|
(if (get-print-state old-port)
|
||||||
|
(port-with-print-state new-port (get-print-state old-port))
|
||||||
|
new-port))
|
|
@ -3246,7 +3246,7 @@
|
||||||
(set-port-encoding! p (let ((t enc)) (if t t "UTF-8")))
|
(set-port-encoding! p (let ((t enc)) (if t t "UTF-8")))
|
||||||
(let f ((x (read p)) (result '()))
|
(let f ((x (read p)) (result '()))
|
||||||
(if (eof-object? x)
|
(if (eof-object? x)
|
||||||
(begin (close-input-port p) (reverse result))
|
(begin (close-port p) (reverse result))
|
||||||
(f (read p) (cons (datum->syntax k x) result)))))))))
|
(f (read p) (cons (datum->syntax k x) result)))))))))
|
||||||
(let ((src (syntax-source x)))
|
(let ((src (syntax-source x)))
|
||||||
(let ((file (if src (assq-ref src 'filename) #f)))
|
(let ((file (if src (assq-ref src 'filename) #f)))
|
||||||
|
|
|
@ -3183,7 +3183,7 @@
|
||||||
(result '()))
|
(result '()))
|
||||||
(if (eof-object? x)
|
(if (eof-object? x)
|
||||||
(begin
|
(begin
|
||||||
(close-input-port p)
|
(close-port p)
|
||||||
(reverse result))
|
(reverse result))
|
||||||
(f (read p)
|
(f (read p)
|
||||||
(cons (datum->syntax k x) result)))))))
|
(cons (datum->syntax k x) result)))))))
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue