From 9cd528ca08db48df3af9e91883d02079e6293646 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sat, 3 May 2014 19:43:49 -0600 Subject: [PATCH] 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. --- .../mzscheme-doc/mzscheme/mzscheme.scrbl | 13 +++++++++---- .../racket-doc/scribblings/reference/exns.scrbl | 2 +- .../scribblings/reference/file-ports.scrbl | 12 +++++++++++- .../scribblings/reference/module-reflect.scrbl | 2 +- .../racket-pkgs/racket-test/tests/racket/file.rktl | 7 +++++++ racket/collects/racket/private/kw-file.rkt | 4 ++-- racket/src/racket/src/port.c | 14 +++++++++++--- racket/src/racket/src/portfun.c | 2 +- 8 files changed, 43 insertions(+), 13 deletions(-) diff --git a/pkgs/mzscheme-pkgs/mzscheme-doc/mzscheme/mzscheme.scrbl b/pkgs/mzscheme-pkgs/mzscheme-doc/mzscheme/mzscheme.scrbl index 6074000da3..2edeb7b510 100644 --- a/pkgs/mzscheme-pkgs/mzscheme-doc/mzscheme/mzscheme.scrbl +++ b/pkgs/mzscheme-pkgs/mzscheme-doc/mzscheme/mzscheme.scrbl @@ -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] diff --git a/pkgs/racket-pkgs/racket-doc/scribblings/reference/exns.scrbl b/pkgs/racket-pkgs/racket-doc/scribblings/reference/exns.scrbl index 29fc297c6a..243f6c3d6d 100644 --- a/pkgs/racket-pkgs/racket-doc/scribblings/reference/exns.scrbl +++ b/pkgs/racket-pkgs/racket-doc/scribblings/reference/exns.scrbl @@ -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?]) diff --git a/pkgs/racket-pkgs/racket-doc/scribblings/reference/file-ports.scrbl b/pkgs/racket-pkgs/racket-doc/scribblings/reference/file-ports.scrbl index 809137db2d..907a1c9f43 100644 --- a/pkgs/racket-pkgs/racket-doc/scribblings/reference/file-ports.scrbl +++ b/pkgs/racket-pkgs/racket-doc/scribblings/reference/file-ports.scrbl @@ -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 diff --git a/pkgs/racket-pkgs/racket-doc/scribblings/reference/module-reflect.scrbl b/pkgs/racket-pkgs/racket-doc/scribblings/reference/module-reflect.scrbl index 8b3bf8a13f..6e656fa085 100644 --- a/pkgs/racket-pkgs/racket-doc/scribblings/reference/module-reflect.scrbl +++ b/pkgs/racket-pkgs/racket-doc/scribblings/reference/module-reflect.scrbl @@ -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}.} diff --git a/pkgs/racket-pkgs/racket-test/tests/racket/file.rktl b/pkgs/racket-pkgs/racket-test/tests/racket/file.rktl index 1fc532c0d0..17d32ca0a9 100644 --- a/pkgs/racket-pkgs/racket-test/tests/racket/file.rktl +++ b/pkgs/racket-pkgs/racket-test/tests/racket/file.rktl @@ -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)) diff --git a/racket/collects/racket/private/kw-file.rkt b/racket/collects/racket/private/kw-file.rkt index 1f60000d66..d20c972548 100644 --- a/racket/collects/racket/private/kw-file.rkt +++ b/racket/collects/racket/private/kw-file.rkt @@ -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]) diff --git a/racket/src/racket/src/port.c b/racket/src/racket/src/port.c index 78d976a17d..0096cef72f 100644 --- a/racket/src/racket/src/port.c +++ b/racket/src/racket/src/port.c @@ -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; diff --git a/racket/src/racket/src/portfun.c b/racket/src/racket/src/portfun.c index 2078243b58..64a89493f5 100644 --- a/racket/src/racket/src/portfun.c +++ b/racket/src/racket/src/portfun.c @@ -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);