mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-04-29 19:30:36 +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 \
|
||||
\
|
||||
ice-9/boot-9.scm \
|
||||
ice-9/ports.scm \
|
||||
ice-9/r5rs.scm \
|
||||
ice-9/deprecated.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;
|
||||
SCM_SYMBOL (sym_relative, "relative");
|
||||
SCM_SYMBOL (sym_absolute, "absolute");
|
||||
static SCM sym_relative;
|
||||
static SCM sym_absolute;
|
||||
|
||||
static SCM
|
||||
fport_canonicalize_filename (SCM filename)
|
||||
|
@ -677,16 +677,34 @@ scm_init_fports_keywords ()
|
|||
k_encoding = scm_from_latin1_keyword ("encoding");
|
||||
}
|
||||
|
||||
static void
|
||||
scm_init_ice_9_fports (void)
|
||||
{
|
||||
#include "libguile/fports.x"
|
||||
}
|
||||
|
||||
void
|
||||
scm_init_fports ()
|
||||
{
|
||||
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 ();
|
||||
scm_c_define ("%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
|
||||
|
||||
|
||||
static void
|
||||
scm_init_ice_9_ioext (void)
|
||||
{
|
||||
#include "libguile/ioext.x"
|
||||
}
|
||||
|
||||
void
|
||||
scm_init_ioext ()
|
||||
{
|
||||
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
|
||||
|
||||
SCM_DEFINE (scm_set_current_input_port, "set-current-input-port", 1, 0, 0,
|
||||
(SCM port),
|
||||
"@deffnx {Scheme Procedure} set-current-output-port port\n"
|
||||
"@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
|
||||
scm_set_current_input_port (SCM port)
|
||||
#define FUNC_NAME "set-current-input-port"
|
||||
{
|
||||
SCM oinp = scm_fluid_ref (cur_inport_fluid);
|
||||
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
|
||||
|
||||
|
||||
SCM_DEFINE (scm_set_current_output_port, "set-current-output-port", 1, 0, 0,
|
||||
(SCM port),
|
||||
"Set the current default output port to @var{port}.")
|
||||
#define FUNC_NAME s_scm_set_current_output_port
|
||||
SCM
|
||||
scm_set_current_output_port (SCM port)
|
||||
#define FUNC_NAME "scm-set-current-output-port"
|
||||
{
|
||||
SCM ooutp = scm_fluid_ref (cur_outport_fluid);
|
||||
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
|
||||
|
||||
|
||||
SCM_DEFINE (scm_set_current_error_port, "set-current-error-port", 1, 0, 0,
|
||||
(SCM port),
|
||||
"Set the current default error port to @var{port}.")
|
||||
#define FUNC_NAME s_scm_set_current_error_port
|
||||
SCM
|
||||
scm_set_current_error_port (SCM port)
|
||||
#define FUNC_NAME "set-current-error-port"
|
||||
{
|
||||
SCM oerrp = scm_fluid_ref (cur_errport_fluid);
|
||||
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
|
||||
|
||||
|
||||
SCM
|
||||
scm_set_current_warning_port (SCM port)
|
||||
#define FUNC_NAME "set-current-warning-port"
|
||||
|
@ -482,7 +472,6 @@ scm_set_current_warning_port (SCM port)
|
|||
}
|
||||
#undef FUNC_NAME
|
||||
|
||||
|
||||
void
|
||||
scm_dynwind_current_input_port (SCM port)
|
||||
#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 string, that is the encoding. If it is #f, it is in the "native"
|
||||
(Latin-1) encoding. */
|
||||
SCM_VARIABLE (default_port_encoding_var, "%default-port-encoding");
|
||||
|
||||
static int scm_port_encoding_init = 0;
|
||||
static SCM default_port_encoding_var;
|
||||
|
||||
/* Use ENCODING as the default encoding for future ports. */
|
||||
void
|
||||
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"))
|
||||
scm_fluid_set_x (SCM_VARIABLE_REF (default_port_encoding_var), SCM_BOOL_F);
|
||||
else
|
||||
|
@ -940,63 +922,41 @@ scm_i_set_default_port_encoding (const char *encoding)
|
|||
const char *
|
||||
scm_i_default_port_encoding (void)
|
||||
{
|
||||
if (!scm_port_encoding_init)
|
||||
return "ISO-8859-1";
|
||||
else if (!scm_is_fluid (SCM_VARIABLE_REF (default_port_encoding_var)))
|
||||
SCM encoding;
|
||||
|
||||
encoding = scm_fluid_ref (SCM_VARIABLE_REF (default_port_encoding_var));
|
||||
if (!scm_is_string (encoding))
|
||||
return "ISO-8859-1";
|
||||
else
|
||||
{
|
||||
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);
|
||||
}
|
||||
return scm_i_string_chars (encoding);
|
||||
}
|
||||
|
||||
/* 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;
|
||||
static SCM default_conversion_strategy_var;
|
||||
|
||||
/* The possible conversion strategies. */
|
||||
SCM_SYMBOL (sym_error, "error");
|
||||
SCM_SYMBOL (sym_substitute, "substitute");
|
||||
SCM_SYMBOL (sym_escape, "escape");
|
||||
static SCM sym_error;
|
||||
static SCM sym_substitute;
|
||||
static SCM sym_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;
|
||||
SCM value;
|
||||
|
||||
if (!scm_conversion_strategy_init
|
||||
|| !scm_is_fluid (SCM_VARIABLE_REF (default_conversion_strategy_var)))
|
||||
handler = SCM_FAILED_CONVERSION_QUESTION_MARK;
|
||||
value = scm_fluid_ref (SCM_VARIABLE_REF (default_conversion_strategy_var));
|
||||
|
||||
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
|
||||
{
|
||||
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;
|
||||
/* Default to 'error also when the fluid's value is not one of
|
||||
the valid symbols. */
|
||||
return SCM_FAILED_CONVERSION_ERROR;
|
||||
}
|
||||
|
||||
/* 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;
|
||||
|
||||
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:
|
||||
|
@ -3286,36 +3241,16 @@ SCM_DEFINE (scm_sys_make_void_port, "%make-void-port", 1, 0, 0,
|
|||
|
||||
/* Initialization. */
|
||||
|
||||
void
|
||||
scm_init_ports ()
|
||||
static void
|
||||
scm_init_ice_9_ports (void)
|
||||
{
|
||||
#include "libguile/ports.x"
|
||||
|
||||
/* lseek() symbols. */
|
||||
scm_c_define ("SEEK_SET", scm_from_int (SEEK_SET));
|
||||
scm_c_define ("SEEK_CUR", scm_from_int (SEEK_CUR));
|
||||
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
|
||||
al into parameters. They are then removed from the guile module. */
|
||||
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);
|
||||
}
|
||||
|
||||
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:
|
||||
c-file-style: "gnu"
|
||||
|
|
|
@ -88,6 +88,7 @@ SOURCES = \
|
|||
ice-9/poe.scm \
|
||||
ice-9/poll.scm \
|
||||
ice-9/popen.scm \
|
||||
ice-9/ports.scm \
|
||||
ice-9/posix.scm \
|
||||
ice-9/pretty-print.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}
|
||||
;;;
|
||||
|
||||
|
@ -315,11 +283,10 @@ file with the given name already exists, the effect is unspecified."
|
|||
(for-eachn (cdr l1) (map cdr rest))))))))
|
||||
|
||||
|
||||
;; Temporary definition used in the include-from-path expansion;
|
||||
;; replaced later.
|
||||
;; Temporary definitions used by `include'; replaced later.
|
||||
|
||||
(define (absolute-file-name? file-name)
|
||||
#t)
|
||||
(define (absolute-file-name? file-name) #t)
|
||||
(define (open-input-file str) (open-file str "r"))
|
||||
|
||||
;;; {and-map and or-map}
|
||||
;;;
|
||||
|
@ -1195,11 +1162,6 @@ VALUE."
|
|||
;;
|
||||
;; 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
|
||||
(define record-type-vtable
|
||||
(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}
|
||||
;;;
|
||||
|
||||
|
@ -1483,140 +1422,6 @@ CONV is not applied to the initial value."
|
|||
;;; {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)
|
||||
"Calls the one-argument procedure @var{proc} with a newly created output
|
||||
port. When the function returns, the string composed of the characters
|
||||
|
@ -1625,18 +1430,6 @@ written into the port is returned."
|
|||
(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))))
|
||||
|
||||
|
||||
|
||||
;;; {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)
|
||||
(if 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
|
||||
;;; 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")))
|
||||
(let f ((x (read p)) (result '()))
|
||||
(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)))))))))
|
||||
(let ((src (syntax-source x)))
|
||||
(let ((file (if src (assq-ref src 'filename) #f)))
|
||||
|
|
|
@ -3183,7 +3183,7 @@
|
|||
(result '()))
|
||||
(if (eof-object? x)
|
||||
(begin
|
||||
(close-input-port p)
|
||||
(close-port p)
|
||||
(reverse result))
|
||||
(f (read p)
|
||||
(cons (datum->syntax k x) result)))))))
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue