diff --git a/collects/scribblings/reference/paths.scrbl b/collects/scribblings/reference/paths.scrbl index 2024b22762..4fb1f14b84 100644 --- a/collects/scribblings/reference/paths.scrbl +++ b/collects/scribblings/reference/paths.scrbl @@ -103,7 +103,7 @@ the conversion of Windows paths. See also @racket[some-system-path->string].} -@defproc[(path->bytes [path path?]) bytes?]{ +@defproc[(path->bytes [path path-for-some-system?]) bytes?]{ Produces @racket[path]'s byte string representation. No information is lost in this translation, so that @racket[(bytes->path (path->bytes @@ -138,7 +138,7 @@ As for @racket[path->string], information can be lost from @defproc[(bytes->path-element [bstr bytes?] [type (or/c 'unix 'windows) (system-path-convention-type)]) - path?]{ + path-for-some-system?]{ Like @racket[bytes->path], except that @racket[bstr] corresponds to a single relative element in a path. In terms of conversions and @@ -186,7 +186,7 @@ reassembling the result with @racket[bytes->path-element] and @racket[build-path]).} -@defproc[(path-convention-type [path path?]) +@defproc[(path-convention-type [path path-for-some-system?]) (or/c 'unix 'windows)]{ Accepts a path value (not a string) and returns its convention @@ -201,11 +201,11 @@ Returns the path convention type of the current platform: Windows.} -@defproc[(build-path [base (or/c path-string? 'up 'same)] - [sub (or/c (and/c path-string? +@defproc[(build-path [base (or/c path-string? path-for-some-system? 'up 'same)] + [sub (or/c (and/c (or/c path-string? path-for-some-system?) (not/c complete-path?)) (or/c 'up 'same))] ...) - path?]{ + path-for-some-system?]{ Creates a path given a base path and any number of sub-path extensions. If @racket[base] is an absolute path, the result is an @@ -219,7 +219,7 @@ drive specification (with or without a trailing slash) the first @racket[sub] can be an absolute (driveless) path. For all platforms, the last @racket[sub] can be a filename. -The @racket[base] and @racket[sub-paths] arguments can be paths for +The @racket[base] and @racket[sub] arguments can be paths for any platform. The platform for the resulting path is inferred from the @racket[base] and @racket[sub] arguments, where string arguments imply a path for the current platform. If different arguments are for @@ -261,15 +261,18 @@ Windows examples. ]} -@defproc[(build-path/convention-type [type (or/c 'unix 'windows)] - [base path-string?] - [sub (or/c path-string? 'up 'same)] ...) - path?]{ +@defproc[(build-path/convention-type + [type (or/c 'unix 'windows)] + [base (or/c path-string? path-for-some-system? 'up 'same)] + [sub (or/c (and/c (or/c path-string? path-for-some-system?) + (not/c complete-path?)) + (or/c 'up 'same))] ...) + path-for-some-system?]{ Like @racket[build-path], except a path convention type is specified explicitly.} -@defproc[(absolute-path? [path path-string?]) boolean?]{ +@defproc[(absolute-path? [path (or/c path-string? path-for-some-system?)]) boolean?]{ Returns @racket[#t] if @racket[path] is an absolute path, @racket[#f] otherwise. The @racket[path] argument can be a path for any @@ -278,7 +281,7 @@ contains a nul character), @racket[#f] is returned. This procedure does not access the filesystem.} -@defproc[(relative-path? [path path-string?]) boolean?]{ +@defproc[(relative-path? [path (or/c path-string? path-for-some-system?)]) boolean?]{ Returns @racket[#t] if @racket[path] is a relative path, @racket[#f] otherwise. The @racket[path] argument can be a path for any @@ -287,7 +290,7 @@ contains a nul character), @racket[#f] is returned. This procedure does not access the filesystem.} -@defproc[(complete-path? [path path-string?]) boolean?]{ +@defproc[(complete-path? [path (or/c path-string? path-for-some-system?)]) boolean?]{ Returns @racket[#t] if @racket[path] is a completely determined path (@italic{not} relative to a directory or drive), @racket[#f] @@ -300,9 +303,9 @@ contains a nul character), @racket[#f] is returned. This procedure does not access the filesystem.} -@defproc[(path->complete-path [path path-string?] - [base path-string? (current-directory)]) - path?]{ +@defproc[(path->complete-path [path (or/c path-string? path-for-some-system?)] + [base (or/c path-string? path-for-some-system?) (current-directory)]) + path-for-some-system?]{ Returns @racket[path] as a complete path. If @racket[path] is already a complete path, it is returned as the result. Otherwise, @@ -317,7 +320,8 @@ platforms, the @exnraise[exn:fail:contract]. This procedure does not access the filesystem.} -@defproc[(path->directory-path [path path-string?]) path?]{ +@defproc[(path->directory-path [path (or/c path-string? path-for-some-system?)]) + path-for-some-system?]{ Returns @racket[path] if @racket[path] syntactically refers to a directory and ends in a separator, otherwise it returns an extended @@ -341,13 +345,14 @@ owning @racket[path]), otherwise @racket[path] is returned (after expansion).} -@defproc[(cleanse-path [path path-string?]) path]{ +@defproc[(cleanse-path [path (or/c path-string? path-for-some-system?)]) + path-for-some-system?]{ @techlink{Cleanse}s @racket[path] (as described at the beginning of this chapter) without consulting the filesystem.} -@defproc[(expand-user-path [path path-string?]) path]{ +@defproc[(expand-user-path [path path-string?]) path?]{ @techlink{Cleanse}s @racket[path]. In addition, under @|AllUnix|, a leading @litchar{~} is treated as user's home directory and expanded; @@ -356,7 +361,9 @@ of the path), where @litchar{~} by itself indicates the home directory of the current user.} -@defproc[(simplify-path [path path-string?] [use-filesystem? boolean? #t]) path?]{ +@defproc[(simplify-path [path (or/c path-string? path-for-some-system?)] + [use-filesystem? boolean? #t]) + path-for-some-system?]{ Eliminates redundant path separators (except for a single trailing separator), up-directory @litchar{..}, and same-directory @litchar{.} @@ -364,7 +371,7 @@ indicators in @racket[path], and changes @litchar{/} separators to @litchar{\} separators in Windows paths, such that the result accesses the same file or directory (if it exists) as @racket[path]. -In general, the pathname is normalized as much as possible --- without +In general, the pathname is normalized as much as possible---without consulting the filesystem if @racket[use-filesystem?] is @racket[#f], and (under Windows) without changing the case of letters within the path. If @racket[path] syntactically refers to a directory, the @@ -401,7 +408,8 @@ See @secref["unixpaths"] for more information on simplifying information on simplifying Windows paths.} -@defproc[(normal-case-path [path path-string?]) path?]{ +@defproc[(normal-case-path [path (or/c path-string? path-for-some-system?)]) + path-for-some-system?]{ Returns @racket[path] with ``normalized'' case letters. For @|AllUnix| paths, this procedure always returns the input path, because @@ -419,9 +427,9 @@ different on the current platform than for the path's platform. This procedure does not access the filesystem.} -@defproc[(split-path [path path-string?]) - (values (or/c path? 'relative #f) - (or/c path? 'up 'same) +@defproc[(split-path [path (or/c path-string? path-for-some-system?)]) + (values (or/c path-for-some-system? 'relative #f) + (or/c path-for-some-system? 'up 'same) boolean?)]{ Deconstructs @racket[path] into a smaller path and an immediate @@ -469,9 +477,9 @@ See @secref["unixpaths"] for more information on splitting information on splitting Windows paths.} -@defproc[(path-replace-suffix [path path-string?] +@defproc[(path-replace-suffix [path (or/c path-string? path-for-some-system?)] [suffix (or/c string? bytes?)]) - path?]{ + path-for-some-system?]{ Returns a path that is the same as @racket[path], except that the suffix for the last element of the path is changed to @@ -483,9 +491,9 @@ at the end of the path element, as long as the path element is not path for any platform, and the result is for the same platform. If @racket[path] represents a root, the @exnraise[exn:fail:contract].} -@defproc[(path-add-suffix [path path-string?] +@defproc[(path-add-suffix [path (or/c path-string? path-for-some-system?)] [suffix (or/c string? bytes?)]) - path?]{ + path-for-some-system?]{ Similar to @racket[path-replace-suffix], but any existing suffix on @racket[path] is preserved by replacing every @litchar{.} in the last diff --git a/collects/tests/racket/path.rktl b/collects/tests/racket/path.rktl index 80803d25b3..a6a3618953 100644 --- a/collects/tests/racket/path.rktl +++ b/collects/tests/racket/path.rktl @@ -674,9 +674,8 @@ (test (string->path "\\\\?\\RED\\..\\..") normal-case-path (coerce "\\\\?\\RED\\..\\..")) ;; cleanse-path removes redundant backslashes - (when (eq? 'windows (system-type)) - (test (string->path "\\\\?\\\\UNC\\x\\y") cleanse-path (coerce "\\\\?\\\\UNC\\x\\y")) - (test (string->path "\\\\?\\c:\\") cleanse-path (coerce "\\\\?\\c:\\\\"))) + (test (string->path "\\\\?\\\\UNC\\x\\y") cleanse-path (coerce "\\\\?\\\\UNC\\x\\y")) + (test (string->path "\\\\?\\c:\\") cleanse-path (coerce "\\\\?\\c:\\\\")) ;; cleanse-path removes redundant backslashes, and ;; simplify-path uses cleanse-path under Windows: @@ -690,9 +689,9 @@ (test (string->path "\\\\?\\UNC\\a\\b\\.") cleanse-path (coerce "\\\\?\\UNC\\\\a\\b\\\\.")) (test (string->path "\\\\?\\RED\\\\..") cleanse-path (coerce "\\\\?\\RED\\..")) (test (string->path "\\\\?\\") cleanse-path (coerce "\\\\?\\\\")))]) + (go cleanse-path) + (test (string->path "\\\\?\\c:") cleanse-path (coerce "\\\\?\\c:")) (when (eq? 'windows (system-type)) - (go cleanse-path) - (test (string->path "\\\\?\\c:") cleanse-path (coerce "\\\\?\\c:")) (go simplify-path)) (go (lambda (p) (simplify-path p #f))) (test (string->path "a\\b") simplify-path (coerce "a/b") #f) diff --git a/src/racket/src/file.c b/src/racket/src/file.c index 7bec2a79fb..d62f2d827d 100644 --- a/src/racket/src/file.c +++ b/src/racket/src/file.c @@ -4018,8 +4018,8 @@ static Scheme_Object *resolve_path(int argc, Scheme_Object *argv[]) char *filename; int expanded; - if (!SCHEME_GENERAL_PATH_STRINGP(argv[0])) - scheme_wrong_type("resolve-path", SCHEME_GENERAL_PATH_STRING_STR, 0, argc, argv); + if (!SCHEME_PATH_STRINGP(argv[0])) + scheme_wrong_type("resolve-path", SCHEME_PATH_STRING_STR, 0, argc, argv); filename = do_expand_filename(argv[0], NULL, @@ -4669,10 +4669,15 @@ static Scheme_Object *current_drive(int argc, Scheme_Object *argv[]) static Scheme_Object *cleanse_path(int argc, Scheme_Object *argv[]) { char *filename; - int expanded; + int expanded, kind; - if (!SCHEME_PATH_STRINGP(argv[0])) - scheme_wrong_type("cleanse-path", SCHEME_PATH_STRING_STR, 0, argc, argv); + if (!SCHEME_GENERAL_PATH_STRINGP(argv[0])) + scheme_wrong_type("cleanse-path", SCHEME_GENERAL_PATH_STRING_STR, 0, argc, argv); + + if (SCHEME_GENERAL_PATHP(argv[0])) + kind = SCHEME_PATH_KIND(argv[0]); + else + kind = SCHEME_PLATFORM_PATH_KIND; filename = do_expand_filename(argv[0], NULL, @@ -4681,13 +4686,13 @@ static Scheme_Object *cleanse_path(int argc, Scheme_Object *argv[]) &expanded, 1, 0, 0, /* no security check, since the filesystem is not used */ - SCHEME_PLATFORM_PATH_KIND, + kind, 0); - if (!expanded && SCHEME_PATHP(argv[0])) + if (!expanded && SCHEME_GENERAL_PATHP(argv[0])) return argv[0]; else - return scheme_make_sized_path(filename, strlen(filename), 1); + return scheme_make_sized_offset_kind_path(filename, 0, strlen(filename), 1, kind); } static Scheme_Object *expand_user_path(int argc, Scheme_Object *argv[])