racket/base: add #:for-module? argument to open-input-file

Exposes a feature that is used by the default load handler to
raise `exn:fail:{syntax,filesystem}:missing-module` exceptions.
This commit is contained in:
Matthew Flatt 2014-05-03 19:43:49 -06:00
parent cb322e939a
commit 9cd528ca08
8 changed files with 43 additions and 13 deletions

View File

@ -244,7 +244,9 @@ the field for an instance causes the instance to accept keyword
arguments.)}
@deftogether[(
@defproc[(open-input-file [file path-string?] [mode (one-of/c 'text 'binary) 'binary])
@defproc[(open-input-file [file path-string?]
[mode (one-of/c 'text 'binary) 'binary]
[module-mode (or-of/c 'module 'none) 'none])
input-port?]
@defproc[(open-output-file [file path-string?]
[mode (one-of/c 'text 'binary) 'binary]
@ -279,10 +281,13 @@ arguments.)}
)]{
Like @base-open-input-file, etc. from @racketmodname[scheme/base], but
@racket[mode] and @racket[exists] arguments are not keyword
arguments. When both @racket[mode] and @racket[exists] are accepted,
they are accepted in either order.}
the @racket[mode], @racket[exists], and @racket[module-mode]
(corresponds to @racket[#:for-module?]) arguments are not keyword
arguments. When both @racket[mode] and @racket[exists] or
@racket[module-mode] are accepted, they are accepted in either order.
@history[#:changed "6.0.1.6"
@elem{Added the @scheme[module-mode] argument to @racket[open-input-file].}]}
@deftogether[(
@defproc[(syntax-object->datum [stx syntax?]) any]

View File

@ -752,7 +752,7 @@ category of the error code: @racket['posix] indicates a C/Posix
code (under Windows, only), and @racket['gai] indicates a
@tt{getaddrinfo} error code (which shows up only in
@racket[exn:fail:network:errno] exceptions for operations that resolve
hostnames, but it allowed in @racket[exn:fail:filesystem:errno]
hostnames, but is allowed in @racket[exn:fail:filesystem:errno]
instances for consistency).}
@defstruct[(exn:fail:filesystem:missing-module exn:fail:filesystem) ([path module-path?])

View File

@ -46,7 +46,8 @@ the management of the current custodian (see
@secref["custodians"]).
@defproc[(open-input-file [path path-string?]
[#:mode mode-flag (or/c 'binary 'text) 'binary])
[#:mode mode-flag (or/c 'binary 'text) 'binary]
[#:for-module? for-module? any/c #f])
input-port?]{
Opens the file specified by @racket[path] for input. The
@ -93,6 +94,15 @@ to close it more automatically (see @secref["willexecutor"]).
A @tech{path} value that is the @tech{cleanse}d version of
@racket[path] is used as the name of the opened port.
If opening the file fails, if @racket[for-module?] is true, and
@racket[current-module-path-for-load] has a non-@racket[#f] value,
then the raised exception is either
@racket[exn:fail:syntax:missing-module] (if the value of
@racket[current-module-path-for-load] is a @tech{syntax object}) or
@racket[exn:fail:filesystem:missing-module] (otherwise).
@history[#:changed "6.0.1.6" @elem{Added @racket[#:for-module?].}]
@file-examples[
;; put some text in a file
(with-output-to-file some-file

View File

@ -189,7 +189,7 @@ instead of the parameter value.}
A @tech{parameter} that determines a module path used for
@racket[exn:fail:syntax:missing-module] and
@racket[exn:fail:filesytem:missing-module] exceptions as raised by the
@racket[exn:fail:filesystem:missing-module] exceptions as raised by the
default @tech{load handler}. The parameter is normally set by a
@tech{module name resolver}.}

View File

@ -265,6 +265,13 @@
(err/rt-test (open-input-file "x" 8))
(err/rt-test (open-input-file "x" 'something-else))
(err/rt-test (open-input-file "badfile") exn:fail:filesystem:errno?)
(err/rt-test (open-input-file "badfile" #:for-module? #t) exn:fail:filesystem:errno?)
(err/rt-test (parameterize ([current-module-path-for-load 'badfile])
(open-input-file "badfile" #:for-module? #t))
exn:fail:filesystem:missing-module?)
(err/rt-test (parameterize ([current-module-path-for-load #'badfile])
(open-input-file "badfile" #:for-module? #t))
exn:fail:syntax:missing-module?)
(arity-test open-output-file 1 1)
(err/rt-test (open-output-file 8))

View File

@ -24,12 +24,12 @@
(define binary-or-text-desc
"(or/c 'binary 'text)")
(define (open-input-file path #:mode [mode 'binary])
(define (open-input-file path #:mode [mode 'binary] #:for-module? [for-module? #f])
(unless (path-string? path)
(raise-argument-error 'open-input-file "path-string?" path))
(unless (memq mode '(binary text))
(raise-argument-error 'open-input-file binary-or-text-desc mode))
(k:open-input-file path mode))
(k:open-input-file path mode (if for-module? 'module 'none)))
(define (open-output-file path #:mode [mode 'binary]
#:exists [exists 'error])

View File

@ -479,7 +479,7 @@ static Scheme_Object *make_oskit_console_input_port();
static void force_close_output_port(Scheme_Object *port);
static void force_close_input_port(Scheme_Object *port);
ROSYM static Scheme_Object *text_symbol, *binary_symbol;
ROSYM static Scheme_Object *text_symbol, *binary_symbol, *module_symbol;
ROSYM static Scheme_Object *append_symbol, *error_symbol, *update_symbol, *can_update_symbol;
ROSYM static Scheme_Object *replace_symbol, *truncate_symbol, *truncate_replace_symbol;
ROSYM static Scheme_Object *must_truncate_symbol;
@ -515,6 +515,7 @@ scheme_init_port (Scheme_Env *env)
REGISTER_SO(text_symbol);
REGISTER_SO(binary_symbol);
REGISTER_SO(module_symbol);
REGISTER_SO(append_symbol);
REGISTER_SO(error_symbol);
REGISTER_SO(replace_symbol);
@ -526,6 +527,7 @@ scheme_init_port (Scheme_Env *env)
text_symbol = scheme_intern_symbol("text");
binary_symbol = scheme_intern_symbol("binary");
module_symbol = scheme_intern_symbol("module");
append_symbol = scheme_intern_symbol("append");
error_symbol = scheme_intern_symbol("error");
replace_symbol = scheme_intern_symbol("replace");
@ -4604,7 +4606,7 @@ scheme_do_open_input_file(char *name, int offset, int argc, Scheme_Object *argv[
#endif
char *filename;
int regfile, i;
int m_set = 0;
int m_set = 0, mm_set = 0;
Scheme_Object *result;
if (!SCHEME_PATH_STRINGP(argv[0]))
@ -4622,6 +4624,12 @@ scheme_do_open_input_file(char *name, int offset, int argc, Scheme_Object *argv[
} else if (SAME_OBJ(argv[i], binary_symbol)) {
/* This is the default */
m_set++;
} else if (SAME_OBJ(argv[i], module_symbol)) {
mm_set++;
for_module = 1;
} else if (SAME_OBJ(argv[i], scheme_none_symbol)) {
mm_set++;
for_module = 1;
} else {
char *astr;
intptr_t alen;
@ -4634,7 +4642,7 @@ scheme_do_open_input_file(char *name, int offset, int argc, Scheme_Object *argv[
astr, alen);
}
if (m_set > 1) {
if ((m_set > 1) || (mm_set > 1)) {
char *astr;
intptr_t alen;

View File

@ -243,7 +243,7 @@ scheme_init_port_fun(Scheme_Env *env)
GLOBAL_FOLDING_PRIM("terminal-port?", scheme_terminal_port_p, 1, 1, 1, env);
GLOBAL_PRIM_W_ARITY("port-closed?", port_closed_p, 1, 1, env);
GLOBAL_PRIM_W_ARITY("open-input-file", open_input_file, 1, 2, env);
GLOBAL_PRIM_W_ARITY("open-input-file", open_input_file, 1, 3, env);
GLOBAL_PRIM_W_ARITY("open-input-bytes", open_input_byte_string, 1, 2, env);
GLOBAL_PRIM_W_ARITY("open-input-string", open_input_char_string, 1, 2, env);
GLOBAL_PRIM_W_ARITY("open-output-file", open_output_file, 1, 3, env);