doc work, epseciall I/O and OS reference
svn: r6808
This commit is contained in:
parent
4bf593ddc4
commit
cec0624357
|
@ -14,6 +14,9 @@
|
|||
(provide PLaneT)
|
||||
(define PLaneT "PLaneT")
|
||||
|
||||
(provide etc)
|
||||
(define etc "etc.") ; so we can fix the latex space, one day
|
||||
|
||||
(define-code schemeblock0 to-paragraph)
|
||||
(define-code schemeblock (to-paragraph/prefix (hspace 2)
|
||||
(hspace 2)
|
||||
|
@ -95,7 +98,7 @@
|
|||
(provide onscreen menuitem defterm
|
||||
schemefont schemevalfont schemeresultfont schemeidfont
|
||||
schemeparenfont schemekeywordfont schememetafont schememodfont
|
||||
file exec
|
||||
file exec envvar Flag DFlag
|
||||
link procedure
|
||||
idefterm)
|
||||
|
||||
|
@ -128,6 +131,12 @@
|
|||
(make-element 'tt (append (list "\"") (decode-content str) (list "\""))))
|
||||
(define (exec . str)
|
||||
(make-element 'tt (decode-content str)))
|
||||
(define (Flag . str)
|
||||
(make-element 'tt (cons "-" (decode-content str))))
|
||||
(define (DFlag . str)
|
||||
(make-element 'tt (cons "--" (decode-content str))))
|
||||
(define (envvar . str)
|
||||
(make-element 'tt (decode-content str)))
|
||||
(define (procedure . str)
|
||||
(make-element "schemeresult" (append (list "#<procedure:") (decode-content str) (list ">"))))
|
||||
|
||||
|
|
|
@ -396,10 +396,9 @@
|
|||
r)))]
|
||||
[(*peek #rx#"^$")
|
||||
(if end-token
|
||||
(read-error 'eof "missing closing `~a'~a" end-token
|
||||
(if start-line
|
||||
(format " (started at ~a:~a)" start-line start-col)
|
||||
""))
|
||||
(read-error* start-line start-col start-pos
|
||||
(and pos start-pos (- pos start-pos))
|
||||
'eof "missing closing `~a'" end-token)
|
||||
(done-lines r))]
|
||||
[else (read-error "internal error [get-lines*]")])))))
|
||||
|
||||
|
|
|
@ -313,21 +313,34 @@ The arguments implement the port as follows:
|
|||
|
||||
}
|
||||
|
||||
When @scheme[read-in] or @scheme[peek] (or an event produced by one of
|
||||
these) returns a procedure, and the procedure is used to obtain a
|
||||
When @scheme[read-in] or @scheme[peek] (or an event produced by one
|
||||
of these) returns a procedure, and the procedure is used to obtain a
|
||||
non-byte result. (This non-byte result is @italic{not} intended to
|
||||
return a character or @scheme[eof]; in particular, @scheme[read-char]
|
||||
raises an exception if it encounters a non-byte from a port.) The
|
||||
procedure is called by @scheme[read], @scheme[read-syntax],
|
||||
@scheme[read-honu], @scheme[read-honu-syntax],
|
||||
@scheme[read-byte-or-special], @scheme[read-char-or-special],
|
||||
@scheme[peek-byte-or-special], or @scheme[peek-char-or-special]---or,
|
||||
more precisely, by the default port read handler (see
|
||||
@secref["mz:portreadhandler"]). The special-value procedure can return
|
||||
an arbitrary value, and it will be called zero or one times (not
|
||||
necessarily before further reads or peeks from the port). See
|
||||
@secref["mz:reader-procs"] for more details on the procedure's
|
||||
arguments and result.
|
||||
raises an exception if it encounters a special-result procedure, even
|
||||
if the procedure produces a byte.) A special-result procedure must
|
||||
accept four arguments, and it can optionally accept zero arguments:
|
||||
|
||||
@itemize{
|
||||
|
||||
@item{When the special read is triggered by @scheme[read-syntax],
|
||||
@scheme[read-honu-syntax], or @scheme[read-syntax/recursive], the
|
||||
procedure is passed four arguments that represent a source
|
||||
location.}
|
||||
|
||||
@item{When the special read is triggered by @scheme[read],
|
||||
@scheme[read-honu], @scheme[read-byte-or-special],
|
||||
@scheme[read-char-or-special], @scheme[peek-byte-or-special], or
|
||||
@scheme[peek-char-or-special], the procedure is passed no arguments
|
||||
if it accepts zero arguments, otherwise it is passed four arguments
|
||||
that are all @scheme[#f].}
|
||||
|
||||
}
|
||||
|
||||
The special-value procedure can return an arbitrary value, and it
|
||||
will be called zero or one times (not necessarily before further
|
||||
reads or peeks from the port). See @secref["mz:reader-procs"] for
|
||||
more details on the procedure's result.
|
||||
|
||||
If @scheme[read-in] or @scheme[peek] returns a special
|
||||
procedure when called by any reading procedure other than
|
||||
|
|
70
collects/scribblings/reference/custom-write.scrbl
Normal file
70
collects/scribblings/reference/custom-write.scrbl
Normal file
|
@ -0,0 +1,70 @@
|
|||
#reader(lib "docreader.ss" "scribble")
|
||||
@require["mz.ss"]
|
||||
|
||||
@title{Printer Extension}
|
||||
|
||||
@defthing[prop:custom-write struct-type-property?]{
|
||||
|
||||
Associates a procedure to a structure type to used by the default
|
||||
printer to @scheme[display] or @scheme[write] (or @scheme[print])
|
||||
instances of the structure type.
|
||||
|
||||
@moreref["mz:structprops"]{structure type properties}
|
||||
|
||||
The procedure for a @scheme[prop:custom-write] value takes three
|
||||
arguments: the structure to be printed, the target port, and a boolean
|
||||
that is @scheme[#t] for @scheme[write] mode and @scheme[#f] for
|
||||
@scheme[display] mode. The procedure should print the value to the
|
||||
given port using @scheme[write], @scheme[display], @scheme[fprintf],
|
||||
@scheme[write-special], etc.
|
||||
|
||||
The write handler, display handler, and print handler are specially
|
||||
configured for a port given to a custom-write procedure. Printing to
|
||||
the port through @scheme[display], @scheme[write], or @scheme[print]
|
||||
prints a value recursively with sharing annotations. To avoid a
|
||||
recursive print (i.e., to print without regard to sharing with a value
|
||||
currently being printed), print instead to a string or pipe and
|
||||
transfer the result to the target port using @scheme[write-string] and
|
||||
@scheme[write-special]. To recursively print but to a port other than
|
||||
the one given to the custom-write procedure, copy the given port's
|
||||
write handler, display handler, and print handler to the other port.
|
||||
|
||||
The port given to a custom-write handler is not necessarily the actual
|
||||
target port. In particular, to detect cycles and sharing, the printer
|
||||
invokes a custom-write procedure with a port that records recursive
|
||||
prints, and does not retain any other output.
|
||||
|
||||
Recursive print operations may trigger an escape from the call to the
|
||||
custom-write procedure (e.g., for pretty-printing where a tentative
|
||||
print attempt overflows the line, or for printing error output of a
|
||||
limited width).
|
||||
|
||||
The following example definition of a @scheme[tuple] type includes
|
||||
custom-write procedures that print the tuple's list content using
|
||||
angle brackets in @scheme[write] mode and no brackets in
|
||||
@scheme[display] mode. Elements of the tuple are printed recursively,
|
||||
so that graph and cycle structure can be represented.
|
||||
|
||||
@defexamples[
|
||||
(define (tuple-print tuple port write?)
|
||||
(when write? (write-string "<" port))
|
||||
(let ([l (tuple-ref tuple 0)])
|
||||
(unless (null? l)
|
||||
((if write? write display) (car l) port)
|
||||
(for-each (lambda (e)
|
||||
(write-string ", " port)
|
||||
((if write? write display) e port))
|
||||
(cdr l))))
|
||||
(when write? (write-string ">" port)))
|
||||
|
||||
(define-values (s:tuple make-tuple tuple? tuple-ref tuple-set!)
|
||||
(make-struct-type 'tuple #f 1 0 #f
|
||||
(list (cons prop:custom-write tuple-print))))
|
||||
|
||||
(display (make-tuple '(1 2 "a")))
|
||||
|
||||
(let ([t (make-tuple (list 1 2 "a"))])
|
||||
(set-car! (tuple-ref t 0) t)
|
||||
(write t))
|
||||
]
|
||||
}
|
358
collects/scribblings/reference/filesystem.scrbl
Normal file
358
collects/scribblings/reference/filesystem.scrbl
Normal file
|
@ -0,0 +1,358 @@
|
|||
#reader(lib "docreader.ss" "scribble")
|
||||
@require["mz.ss"]
|
||||
|
||||
@title{Filesystem}
|
||||
|
||||
@;------------------------------------------------------------------------
|
||||
@section[#:tag "mz:findpaths"]{Locating Paths}
|
||||
|
||||
@defproc[(find-system-path [kind symbol?]) path?]{
|
||||
|
||||
Returns a machine-specific path for a standard type of path specified
|
||||
by @scheme[kind], which must be one of the following:
|
||||
|
||||
@itemize{
|
||||
|
||||
@item{@scheme['home-dir] --- the current user's home directory.
|
||||
|
||||
Under Unix and Mac OS X, this directory is determined by expanding
|
||||
the path @file{~}, which is expanded by first checking for a
|
||||
@envvar{HOME} environment variable. If none is defined, the
|
||||
@envvar{USER} and @envvar{LOGNAME} environment variables are
|
||||
consulted (in that order) to find a user name, and then system files
|
||||
are consulted to locate the user's home directory.
|
||||
|
||||
Under Windows, the user's home directory is the user-specific profile
|
||||
directory as determined by the Windows registry. If the registry
|
||||
cannot provide a directory for some reason, the value of the
|
||||
@envvar{USERPROFILE} environment variable is used instead, as long as
|
||||
it refers to a directory that exists. If @envvar{USERPROFILE} also
|
||||
fails, the directory is the one specified by the @envvar{HOMEDRIVE}
|
||||
and @envvar{HOMEPATH} environment variables. If those environment
|
||||
variables are not defined, or if the indicated directory still does
|
||||
not exist, the directory containing the current executable is used as
|
||||
the home directory.}
|
||||
|
||||
@item{@scheme['pref-dir] --- the standard directory for storing the
|
||||
current user's preferences. Under Unix, the directory is
|
||||
@file{.plt-scheme} in the user's home directory. Under Windows, it
|
||||
is @file{PLT Scheme} in the user's application-data folder as
|
||||
specified by the Windows registry; the application-data folder is
|
||||
usually @file{Application Data} in the user's profile
|
||||
directory. Under Mac OS X, it is @file{Library/Preferences} in the
|
||||
user's home directory. This directory might not exist.}
|
||||
|
||||
@item{@scheme['pref-file] --- a file that contains a symbol-keyed
|
||||
association list of preference values. The file's directory path
|
||||
always matches the result returned for @scheme['pref-dir]. The file
|
||||
name is @file{plt-prefs.ss} under Unix and Windows, and it is
|
||||
@file{org.plt-scheme.prefs.ss} under Mac OS X. The file's directory
|
||||
might not exist. See also @scheme[get-preference].}
|
||||
|
||||
@item{@scheme['temp-dir] --- the standard directory for storing
|
||||
temporary files. Under @|AllUnix|, this is the directory specified by
|
||||
the @envvar{TMPDIR} environment variable, if it is defined.}
|
||||
|
||||
@item{@scheme['init-dir] --- the directory containing the
|
||||
initialization file used by stand-alone @exec{mzscheme} executable.
|
||||
It is the same as the current user's home directory.}
|
||||
|
||||
@item{@scheme['init-file] --- the file loaded at start-up
|
||||
by the stand-alone @exec{mzscheme} executable. The directory part
|
||||
of the path is the same path as returned for @scheme['init-dir].
|
||||
The file name is platform-specific:
|
||||
|
||||
@itemize{
|
||||
|
||||
@item{@|AllUnix|: @file{.mzschemerc}}
|
||||
|
||||
@item{Windows: @file{mzschemerc.ss}}
|
||||
|
||||
}}
|
||||
|
||||
@item{@scheme['addon-dir] --- a directory for installing PLT Scheme
|
||||
extensions. It's the same as @scheme['pref-dir], except under Mac OS
|
||||
X, where it is @file{Library/PLT Scheme} in the user's home
|
||||
directory. This directory might not exist.}
|
||||
|
||||
@item{@scheme['doc-dir] --- the standard directory for storing the
|
||||
current user's documents. It's the same as @scheme['home-dir] under
|
||||
@|AllUnix|. Under Windows, it is the user's documents folder as
|
||||
specified by the Windows registry; the documents folder is usually
|
||||
@file{My Documents} in the user's home directory.}
|
||||
|
||||
@item{@scheme['desk-dir] --- the directory for the current user's
|
||||
desktop. Under Unix, it's the same as @scheme['home-dir]. Under
|
||||
Windows, it is the user's desktop folder as specified by the Windows
|
||||
registry; the documents folder is usually @file{Desktop} in the
|
||||
user's home directory. Under Mac OS X, it is the desktop directory,
|
||||
which is specifically @file{~/Desktop} under Mac OS X.}
|
||||
|
||||
@item{@scheme['sys-dir] --- the directory containing the
|
||||
operating system for Windows. Under @|AllUnix|, the
|
||||
result is @scheme["/"].}
|
||||
|
||||
@item{@scheme['exec-file] --- the path of the @exec{mzscheme}
|
||||
executable as provided by the operating system for the current
|
||||
invocation.
|
||||
|
||||
@margin-note{For MrEd, the executable path is the name of a MrEd
|
||||
executable.}}
|
||||
|
||||
@item{@scheme['run-file] --- the path of the current executable; this
|
||||
may be different from result for @scheme['exec-file] because an
|
||||
alternate path was provided through a @DFlag{name} or @Flag{N}
|
||||
command-line flag to the @exec{mzscheme} (or @exec{mred})
|
||||
executable, or because an embedding executable installed an
|
||||
alternate path. In particular a ``launcher'' script created by
|
||||
@scheme[make-mzscheme-launcher] sets this path to the script's
|
||||
path. In the @exec{mzscheme} executable, this path is also bound
|
||||
initially to @scheme[program].}
|
||||
|
||||
@item{@scheme['collects-dir] --- a path to the main collection
|
||||
of libraries (see @secref["mz:mzlib"]). If this path is relative, it's
|
||||
relative to the directory of @scheme[(find-system-path 'exec-file)].
|
||||
This path is normally embedded in the @exec{mzscheme} executable,
|
||||
but it can be overridden by the @DFlag{collects} or @Flag{X}
|
||||
command-line flag.}
|
||||
|
||||
@item{@scheme['orig-dir] --- the current directory at start-up, which
|
||||
can be useful in converting a relative-path result from
|
||||
@scheme[(find-system-path 'exec-file)] or @scheme[(find-system-path
|
||||
'run-file)] to a complete path.}
|
||||
|
||||
}}
|
||||
|
||||
@defproc[(path-list-string->path-list [str (or/c string? bytes?)]
|
||||
[default-path-list (listof path?)])
|
||||
(listof path?)]{
|
||||
|
||||
|
||||
Parses a string or byte string containing a list of paths, and returns
|
||||
a list of path strings. Under @|AllUnix|, paths in a path list are
|
||||
separated by a @litchar{:}; under Windows, paths are separated by a
|
||||
@litchar{;}. Whenever the path list contains an empty path, the list
|
||||
@scheme[default-path-list] is spliced into the returned list of
|
||||
paths. Parts of @scheme[str] that do not form a valid path are not
|
||||
included in the returned list.}
|
||||
|
||||
|
||||
@defproc[(find-executable-path [program-sub path-string?][related-sub path-string?][deepest? any/c #f])
|
||||
(or/c path? false/c)]{
|
||||
|
||||
Finds a path for the executable @scheme[program-sub], returning
|
||||
@scheme[#f] if the path cannot be found.
|
||||
|
||||
If @scheme[related-sub] is not @scheme[#f], then it must be a relative
|
||||
path string, and the path found for @scheme[program-sub] must be such
|
||||
that the file or directory @scheme[related-sub] exists in the same
|
||||
directory as the executable. The result is then the full path for the
|
||||
found @scheme[related-sub], instead of the path for the executable.
|
||||
|
||||
This procedure is used by the @exec{mzscheme} executable to find the
|
||||
standard library collection directory (see @secref["mz:mzlib"]). In
|
||||
this case, @scheme[program] is the name used to start MzScheme and
|
||||
@scheme[related] is @scheme["collects"]. The @scheme[related-sub]
|
||||
argument is used because, under @|AllUnix|, @scheme[program-sub] may
|
||||
involve to a sequence of soft links; in this case,
|
||||
@scheme[related-sub] determines which link in the chain is relevant.
|
||||
|
||||
If @scheme[related-sub] is not @scheme[#f], then when
|
||||
@scheme[find-executable-path] does not finds a @scheme[program-sub]
|
||||
that is a link to another file path, the search can continue with the
|
||||
destination of the link. Further links are inspected until
|
||||
@scheme[related-sub] is found or the end of the chain of links is
|
||||
reached. If @scheme[deepest?] is @scheme[#f] (the default), then the
|
||||
result corresponds to the first path in a chain of links for which
|
||||
@scheme[related-sub] is found (and further links are not actually
|
||||
explored); otherwise, the result corresponds to the last link in the
|
||||
chain for which @scheme[related-sub] is found.
|
||||
|
||||
If @scheme[program-sub] is a pathless name,
|
||||
@scheme[find-executable-path] gets the value of the @envvar{PATH}
|
||||
environment variable; if this environment variable is defined,
|
||||
@scheme[find-executable-path] tries each path in @envvar{PATH} as a
|
||||
prefix for @scheme[program-sub] using the search algorithm described
|
||||
above for path-containing @scheme[program-sub]s. If the @envvar{PATH}
|
||||
environment variable is not defined, @scheme[program-sub] is prefixed
|
||||
with the current directory and used in the search algorithm
|
||||
above. (Under Windows, the current directory is always implicitly the
|
||||
first item in @envvar{PATH}, so @scheme[find-executable-path] checks
|
||||
the current directory first under Windows.)}
|
||||
|
||||
@;------------------------------------------------------------------------
|
||||
@section[#:tag "mz:fileutils"]{Files}
|
||||
|
||||
@defproc[(file-exists? [path path-string?]) boolean?]{
|
||||
|
||||
Returns @scheme[#t] if a file (not a directory) @scheme[path] exists,
|
||||
@scheme[#f] otherwise.
|
||||
|
||||
Under Windows, @scheme[file-exists?] reports @scheme[#t] for all
|
||||
variations of the special filenames (e.g., @scheme["LPT1"],
|
||||
@scheme["x:/baddir/LPT1"]).}
|
||||
|
||||
@defproc[(link-exists? [path path-string?]) boolean?]{
|
||||
|
||||
Returns @scheme[#t] if a link @scheme[path] exists (@|AllUnix|),
|
||||
@scheme[#f] otherwise.
|
||||
|
||||
The predicates @scheme[file-exists?] or @scheme[directory-exists?]
|
||||
work on the final destination of a link or series of links, while
|
||||
@scheme[link-exists?] only follows links to resolve the base part of
|
||||
@scheme[path] (i.e., everything except the last name in the
|
||||
path).
|
||||
|
||||
This procedure never raises the @scheme[exn:fail:filesystem]
|
||||
exception.}
|
||||
|
||||
|
||||
@defproc[(delete-file [path path-string?]) void?]{
|
||||
|
||||
Feletes the file with path @scheme[path] if it exists, otherwise the
|
||||
@exnraise[exn:fail:filesystem]. If @scheme[path] is a link, the link
|
||||
is deleted rather than the destination of the link.}
|
||||
|
||||
@defproc[(rename-file-or-directory [old path-string?]
|
||||
[new path-string?]
|
||||
[exists-ok? any/c #f])
|
||||
void?]{
|
||||
|
||||
Renames the file or directory with path @scheme[old]---if it
|
||||
exists---to the path @scheme[new]. If the file or directory is not
|
||||
renamed successfully, the @exnraise[exn:fail:filesystem].
|
||||
|
||||
This procedure can be used to move a file/directory to a different
|
||||
directory (on the same disk) as well as rename a file/directory within
|
||||
a directory. Unless @scheme[exists-ok?] is provided as a true value,
|
||||
@scheme[new] cannot refer to an existing file or directory. Even if
|
||||
@scheme[exists-ok?] is true, @scheme[new] cannot refer to an existing
|
||||
file when @scheme[old] is a directory, and vice versa. (If
|
||||
@scheme[new] exists and is replaced, the replacement is atomic in the
|
||||
filesystem, except under Windows 95, 98, or Me. However, the check for
|
||||
existence is not included in the atomic action, which means that race
|
||||
conditions are possible when @scheme[exists-ok?] is false or not
|
||||
supplied.)
|
||||
|
||||
If @scheme[old] is a link, the link is renamed rather than the
|
||||
destination of the link, and it counts as a file for replacing any
|
||||
existing @scheme[new].}
|
||||
|
||||
|
||||
@defproc[(file-or-directory-modify-seconds [path path-string?]
|
||||
[secs-n (or/c exact-integer? false/c) #f]
|
||||
[fail-thunk (-> any) (lambda () (raise (make-exn:fail:filesystem ....)))])
|
||||
any]{
|
||||
|
||||
Returns the file or directory's last modification date as
|
||||
platform-specific seconds (see also @secref["mz:time"]) when
|
||||
@scheme[secs-n] is not provided or is @scheme[#f]. (For FAT
|
||||
filesystems under Windows, directories do not have modification
|
||||
dates. Therefore, the creation date is returned for a directory (but
|
||||
the modification date is returned for a file).)
|
||||
|
||||
If @scheme[secs-n] is provided and not @scheme[#f], the access and
|
||||
modification times of @scheme[path] are set to the given time.
|
||||
|
||||
On error (e.g., if no such file exists), @scheme[fail-thunk] is
|
||||
called, and the default @scheme[fail-thunk] raises
|
||||
@scheme[exn:fail:filesystem].}
|
||||
|
||||
|
||||
@defproc[(file-or-directory-permissions [path path-string?]) (listof symbol?)]{
|
||||
|
||||
Returns a list containing @scheme['read], @scheme['write], and/or
|
||||
@scheme['execute] for the given file or directory path. On error
|
||||
(e.g., if no such file exists), the
|
||||
@exnraise[exn:fail:filesystem]. Under @|AllUnix|, permissions are
|
||||
checked for the current effective user instead of the real user.}
|
||||
|
||||
@defproc[(file-size [path path-string?]) nonnegative-exact-integer?]{
|
||||
|
||||
Returns the (logical) size of the specified file in bytes. Under Mac
|
||||
OS X, this size excludes the resource-fork size. On error (e.g., if no
|
||||
such file exists), the @exnraise[exn:fail:filesystem].}
|
||||
|
||||
|
||||
@defproc[(copy-file [src path-string?][dest path-string?]) void?]{
|
||||
|
||||
Creates the file @scheme[dest] as a copy of @scheme[src]. If the file
|
||||
is not successfully copied, the @exnraise[exn:fail:filesystem]. If
|
||||
@scheme[dest] already exists, the copy will fail. File permissions are
|
||||
preserved in the copy. Under Mac OS X, the resource fork is also
|
||||
preserved in the copy. If @scheme[src] refers to a link, the target of
|
||||
the link is copied, rather than the link itself.}
|
||||
|
||||
@defproc[(make-file-or-directory-link [to path-string?][path path-string?])
|
||||
void?]{
|
||||
|
||||
Creates a link @scheme[path] to @scheme[to] under @|AllUnix|. The
|
||||
creation will fail if @scheme[path] already exists. The @scheme[to]
|
||||
need not refer to an existing file or directory, and @scheme[to] is
|
||||
not expanded before writing the link. If the link is not created
|
||||
successfully,the @exnraise[exn:fail:filesystem]. Under Windows, the
|
||||
@exnraise[exn:fail:unsupported] always.}
|
||||
|
||||
@;------------------------------------------------------------------------
|
||||
@section[#:tag "mz:directories"]{Directories}
|
||||
|
||||
See also: @scheme[rename-file-or-directory],
|
||||
@scheme[file-or-directory-modify-seconds],
|
||||
@scheme[file-or-directory-permissions].
|
||||
|
||||
@defparam[current-directory path path-string?]{
|
||||
|
||||
A parameter that determines the current directory for resolving
|
||||
relative paths.
|
||||
|
||||
When the parameter procedure is called to set the current directory,
|
||||
the path argument is expanded using @scheme[expand-path], simplified
|
||||
using @scheme[simplify-path], and then converted to a directory path
|
||||
with @scheme[path->directory-path]; expansion and simplification raise
|
||||
an exception if the path is ill-formed. Thus, the current value of
|
||||
@scheme[current-directory] is always an expanded, simplified,
|
||||
complete, directory path.
|
||||
|
||||
The path is not checked for existence when the parameter is set.}
|
||||
|
||||
|
||||
@defproc[(current-drive) path?]{
|
||||
|
||||
Returns the current drive name Windows. For other platforms, the
|
||||
@exnraise[exn:fail:unsupported]. The current drive is always the drive
|
||||
of the current directory.}
|
||||
|
||||
|
||||
@defproc[(directory-exists? [path path-string?]) boolean?]{
|
||||
|
||||
Returns @scheme[#t] if @scheme[path] refers to a directory,
|
||||
@scheme[#f] otherwise.}
|
||||
|
||||
@defproc[(make-directory [path path-string?]) void?]{
|
||||
|
||||
Creates a new directory with the path @scheme[path]. If the directory
|
||||
is not created successfully, the @exnraise[exn:fail:filesystem].}
|
||||
|
||||
|
||||
@defproc[(delete-directory [path path-string?]) void?]{
|
||||
|
||||
Deletes an existing directory with the path @scheme[path]. If the
|
||||
directory is not deleted successfully, the
|
||||
@exnraise[exn:fail:filesystem].}
|
||||
|
||||
|
||||
@defproc[(directory-list [path path-string? (current-directory)])
|
||||
(listof path?)]{
|
||||
|
||||
Returns a list of all files and directories in the directory specified
|
||||
by @scheme[path]. If @scheme[path] is omitted, a list of files and
|
||||
directories in the current directory is returned. Under @|AllUnix|, an
|
||||
element of the list can start with @litchar{./~} if it would otherwise
|
||||
start with @litchar{~}. Under Windows, an element of the list may
|
||||
start with @litchar["\\\\?\\REL\\\\"].}
|
||||
|
||||
|
||||
@defproc[(filesystem-root-list) (listof path?)]{
|
||||
|
||||
Returns a list of all current root directories. Obtaining this list
|
||||
can be particularly slow under Windows.}
|
|
@ -13,3 +13,4 @@
|
|||
@include-section["reader.scrbl"]
|
||||
@include-section["printer.scrbl"]
|
||||
@include-section["readtables.scrbl"]
|
||||
@include-section["custom-write.scrbl"]
|
||||
|
|
553
collects/scribblings/reference/networking.scrbl
Normal file
553
collects/scribblings/reference/networking.scrbl
Normal file
|
@ -0,0 +1,553 @@
|
|||
#reader(lib "docreader.ss" "scribble")
|
||||
@require["mz.ss"]
|
||||
|
||||
@title[#:tag "mz:networking" #:style 'toc]{Networking}
|
||||
|
||||
@local-table-of-contents[]
|
||||
|
||||
@;------------------------------------------------------------------------
|
||||
@section[#:tag "mz:tcp"]{TCP}
|
||||
|
||||
For information about TCP in general, see @italic{TCP/IP Illustrated,
|
||||
Volume 1} by W. Richard Stevens.
|
||||
|
||||
@defproc[(tcp-listen [port-no (and/c nonnegative-exact-integer?
|
||||
(integer-in 1 65535))]
|
||||
[max-allow-wait nonnegative-exact-integer? 4]
|
||||
[reuse? any/c #f]
|
||||
[hostname (or/c string? false/c) #f])
|
||||
tcp-listener?]
|
||||
|
||||
Creates a ``listening'' server on the local machine at the port number
|
||||
specified by @scheme[port-no]. The @scheme[max-allow-wait] argument
|
||||
determines the maximum number of client connections that can be
|
||||
waiting for acceptance. (When @scheme[max-allow-wait] clients are
|
||||
waiting acceptance, no new client connections can be made.)
|
||||
|
||||
If the @scheme[reuse?] argument is true, then @scheme[tcp-listen] will
|
||||
create a listener even if the port is involved in a @tt{TIME_WAIT}
|
||||
state. Such a use of @scheme[reuse?] defeats certain guarantees of the
|
||||
TCP protocol; see Stevens's book for details. Furthermore, on many
|
||||
modern platforms, a true value for @scheme[reuse?] overrides
|
||||
@tt{TIME_WAIT} only if the listener was previously created with a true
|
||||
value for @scheme[reuse?].
|
||||
|
||||
If @scheme[hostname] is @scheme[#f] (the default), then the listener
|
||||
accepts connections to all of the listening machine's addresses.
|
||||
Otherwise, the listener accepts connections only at the interface(s)
|
||||
associated with the given hostname. For example, providing
|
||||
@scheme["127.0.0.1"] as @scheme[hostname] creates a listener that
|
||||
accepts only connections to @scheme["127.0.0.1"] (the loopback
|
||||
interface) from the local machine.
|
||||
|
||||
(Scheme implements a listener with multiple sockets, if necessary, to
|
||||
accomodate multiple addresses with different protocol families. Under
|
||||
Linux, if @scheme[hostname] maps to both IPv4 and IPv6 addresses, then
|
||||
the behavior depends on whether IPv6 is supported and IPv6 sockets can
|
||||
be configured to listen to only IPv6 connections: if IPv6 is not
|
||||
supported or IPv6 sockets are not configurable, then the IPv6
|
||||
addresses are ignored; otherwise, each IPv6 listener accepts only IPv6
|
||||
connections.)
|
||||
|
||||
The return value of @scheme[tcp-listen] is a TCP listener value. This
|
||||
value can be used in future calls to @scheme[tcp-accept],
|
||||
@scheme[tcp-accept-ready?], and @scheme[tcp-close]. Each new TCP
|
||||
listener value is placed into the management of the current custodian
|
||||
(see @secref["mz:custodians"]).
|
||||
|
||||
If the server cannot be started by @scheme[tcp-listen], the
|
||||
@exnraise[exn:fail:network].}
|
||||
|
||||
|
||||
@defproc[(tcp-connect [hostname string?]
|
||||
[port-no (and/c nonnegative-exact-integer?
|
||||
(integer-in 1 65535))]
|
||||
[local-hostname (or/c string? false/c) #f]
|
||||
[local-port-no (or/c (and/c nonnegative-exact-integer?
|
||||
(integer-in 1 65535))
|
||||
false/c)])
|
||||
(values input-port? output-port?)]{
|
||||
|
||||
Attempts to connect as a client to a listening server. The
|
||||
@scheme[hostname] argument is the server host's Internet address name,
|
||||
and @scheme[port-no] is the port number where the server is listening.
|
||||
|
||||
(If @scheme[hostname] is associated with multiple addresses, they are
|
||||
tried one at a time until a connection succeeds. The name
|
||||
@scheme["localhost"] generally specifies the local machine.)
|
||||
|
||||
The optional @scheme[local-hostname] and @scheme[local-port-no]
|
||||
specify the client's address and port. If both are @scheme[#f] (the
|
||||
default), the client's address and port are selected automatically. If
|
||||
@scheme[local-hostname] is not @scheme[#f], then
|
||||
@scheme[local-port-no] must be non-@scheme[#f]. If
|
||||
@scheme[local-port-no] is non-@scheme[#f] and @scheme[local-hostname]
|
||||
is @scheme[#f], then the given port is used but the address is
|
||||
selected automatically.
|
||||
|
||||
Two values are returned by @scheme[tcp-connect]: an input port and an
|
||||
output port. Data can be received from the server through the input
|
||||
port and sent to the server through the output port. If the server is
|
||||
a @exec{mzscheme} process, it can obtain ports to communicate to the
|
||||
client with @scheme[tcp-accept]. These ports are placed into the
|
||||
management of the current custodian (see @secref["mz:custodians"]).
|
||||
|
||||
Initially, the returned input port is block-buffered, and the returned
|
||||
output port is block-buffered. Change the buffer mode using
|
||||
@scheme[file-stream-buffer-mode].
|
||||
|
||||
Both of the returned ports must be closed to terminate the TCP
|
||||
connection. When both ports are still open, closing the output port
|
||||
with @scheme[close-output-port] sends a TCP close to the server (which
|
||||
is seen as an end-of-file if the server reads the connection through a
|
||||
port). In contrast, @scheme[tcp-abandon-port] (see below) closes the
|
||||
output port, but does not send a TCP close until the input port is
|
||||
also closed.
|
||||
|
||||
Note that the TCP protocol does not support a state where one end is
|
||||
willing to send but not read, nor does it include an automatic message
|
||||
when one end of a connection is fully closed. Instead, the other end
|
||||
of a connection discovers that one end is fully closed only as a
|
||||
response to sending data; in particular, some number of writes on the
|
||||
still-open end may appear to succeed, though writes will eventually
|
||||
produce an error.
|
||||
|
||||
If a connection cannot be established by @scheme[tcp-connect], the
|
||||
@exnraise[exn:fail:network].}
|
||||
|
||||
@defproc[(tcp-connect/enable-break [hostname string?]
|
||||
[port-no (and/c nonnegative-exact-integer?
|
||||
(integer-in 1 65535))]
|
||||
[local-hostname (or/c string? false/c) #f]
|
||||
[local-port-no (or/c (and/c nonnegative-exact-integer?
|
||||
(integer-in 1 65535))
|
||||
false/c)])
|
||||
(values input-port? output-port?)]{
|
||||
|
||||
Like @scheme[tcp-connect], but breaking is enabled (see
|
||||
@secref["mz:breakhandler"]) while trying to connect. If breaking is
|
||||
disabled when @scheme[tcp-connect/enable-break] is called, then either
|
||||
ports are returned or the @scheme[exn:break] exception is raised, but
|
||||
not both.}
|
||||
|
||||
@defproc[(tcp-accept [listener tcp-listener?])
|
||||
(values input-port? output-port?)]{
|
||||
|
||||
Accepts a client connection for the server associated with
|
||||
@scheme[listener], which is a TCP listener value returned by
|
||||
@scheme[tcp-listen]. If no client connection is waiting on the
|
||||
listening port, the call to @scheme[tcp-accept] will block. (See also
|
||||
@scheme[tcp-accept-ready?].)
|
||||
|
||||
Two values are returned by @scheme[tcp-accept]: an input port and an
|
||||
output port. Data can be received from the client through the input
|
||||
port and sent to the client through the output port. These ports are
|
||||
placed into the management of the current custodian (see
|
||||
@secref["mz:custodians"]).
|
||||
|
||||
In terms of buffering and connection states, the ports act the same as
|
||||
ports from @scheme[tcp-connect].
|
||||
|
||||
If a connection cannot be accepted by @scheme[tcp-accept], or if the
|
||||
listener has been closed, the @exnraise[exn:fail:network].}
|
||||
|
||||
|
||||
@defproc[(tcp-accept/enable-break [listener tcp-listener?])
|
||||
(values input-port? output-port?)]{
|
||||
|
||||
Like @scheme[tcp-accept], but breaking is enabled (see
|
||||
@secref["mz:breakhandler"]) while trying to accept a connection. If
|
||||
breaking is disabled when @scheme[tcp-accept/enable-break] is called,
|
||||
then either ports are returned or the @scheme[exn:break] exception is
|
||||
raised, but not both.}
|
||||
|
||||
|
||||
@defproc[(tcp-accept-ready? [listener tcp-listener?]) boolean?]{
|
||||
|
||||
Tests whether an unaccepted client has connected to the server
|
||||
associated with @scheme[listener]. The @scheme[listener] argument is a
|
||||
TCP listener value returned by @scheme[tcp-listen]. If a client is
|
||||
waiting, the return value is @scheme[#t], otherwise it is
|
||||
@scheme[#f]. A client is accepted with the @scheme[tcp-accept]
|
||||
procedure, which returns ports for communicating with the client and
|
||||
removes the client from the list of unaccepted clients.
|
||||
|
||||
If the listener has been closed, the @exnraise[exn:fail:network].}
|
||||
|
||||
|
||||
@defproc[(tcp-close [listener tcp-listener?]) void?]{
|
||||
|
||||
Shuts down the server associated with @scheme[listener]. The
|
||||
@scheme[listener] argument is a TCP listener value returned by
|
||||
@scheme[tcp-listen]. All unaccepted clients receive an end-of-file
|
||||
from the server; connections to accepted clients are unaffected.
|
||||
|
||||
If the listener has already been closed, the @exnraise[exn:fail:network].
|
||||
|
||||
The listener's port number may not become immediately available for
|
||||
new listeners (with the default @scheme[reuse?] argument of
|
||||
@scheme[tcp-listen]). For further information, see Stevens's
|
||||
explanation of the @tt{TIME\_WAIT} TCP state.}
|
||||
|
||||
|
||||
@defproc[(tcp-listener? [v any/c]) boolean?]{
|
||||
|
||||
Returns @scheme[#t] if @scheme[v] is a TCP listener value created by
|
||||
@scheme[tcp-listen], @scheme[#f] otherwise.}
|
||||
|
||||
|
||||
@defproc[(tcp-accept-evt [listener tcp-listener?]) evt?]{
|
||||
|
||||
Returns a @tech{synchronizable event} (see @secref["mz:sync"]) that is
|
||||
in a blocking state when @scheme[tcp-accept] on @scheme[listener]
|
||||
would block. If the event is chosen in a synchronization, the result
|
||||
is a list of two items, which correspond to the two results of
|
||||
@scheme[tcp-accept]. (If the event is not chosen, no connections are
|
||||
accepted.)}
|
||||
|
||||
|
||||
@defproc[(tcp-abandon-port [tcp-port tcp-port?]) void?]{
|
||||
|
||||
Like @scheme[close-output-port] or @scheme[close-input-port]
|
||||
(depending on whether @scheme[tcp-port] is an input or output port),
|
||||
but if @scheme[tcp-port] is an output port and its associated input
|
||||
port is not yet closed, then the other end of the TCP connection does
|
||||
not receive a TCP close message until the input port is also
|
||||
closed.
|
||||
|
||||
The TCP protocol does not include a ``no longer reading'' state on
|
||||
connections, so @scheme[tcp-abandon-port] is equivalent to
|
||||
@scheme[close-input-port] on input TCP ports.}
|
||||
|
||||
|
||||
@defproc[(tcp-addresses [tcp-port tcp-port?]
|
||||
[port-numbers? any/c #f])
|
||||
(or/c (values string? string?)
|
||||
(values string? (integer-in 1 65535)
|
||||
string? (integer-in 1 65535)))]{
|
||||
|
||||
Returns two strings when @scheme[port-numbers?] is @scheme[#f] (the
|
||||
default). The first string is the Internet address for the local
|
||||
machine a viewed by the given TCP port's connection. (For most
|
||||
machines, the answer corresponds to the current machine's only
|
||||
Internet address, but when a machine serves multiple addresses, the
|
||||
result is connection-specific.) The second string is the Internet
|
||||
address for the other end of the connection.
|
||||
|
||||
If @scheme[port-numbers?] is true, then four results are returned: a
|
||||
string for the local machine's address, an exact integer between
|
||||
@scheme[1] and @scheme[65535] for the local machine's port number, a
|
||||
string for the remote machine's address, and an exact integer between
|
||||
@scheme[1] and @scheme[65535] for the remote machine's port number.
|
||||
|
||||
If the given port has been closed, the @exnraise[exn:fail:network].}
|
||||
|
||||
|
||||
@defproc[(tcp-port? [v any/c]) boolean?]{
|
||||
|
||||
Returns @scheme[#t] if @scheme[v] is a port returned by
|
||||
@scheme[tcp-accept], @scheme[tcp-connect],
|
||||
@scheme[tcp-accept/enable-break], or
|
||||
@scheme[tcp-connect/enable-break], @scheme[#f] otherwise.}
|
||||
|
||||
@;------------------------------------------------------------------------
|
||||
@section[#:tag "mz:udp"]{UDP}
|
||||
|
||||
For information about UDP in general, see @italic{TCP/IP Illustrated,
|
||||
Volume 1} by W. Richard Stevens.
|
||||
|
||||
@defproc[(udp-open-socket [family-hostname (or/c string? false/c) #f]
|
||||
[family-port-no (or/c string? false/c) #f])
|
||||
udp?]{
|
||||
|
||||
Creates and returns a UDP socket to send and receive
|
||||
datagrams (broadcasting is allowed). Initially, the socket is not
|
||||
bound or connected to any address or port.
|
||||
|
||||
If @scheme[family-hostname] or @scheme[family-port-no] is not
|
||||
@scheme[#f], then the socket's protocol family is determined from
|
||||
these arguments. The socket is @italic{not} bound to the hostname
|
||||
or port number. For example, the arguments might be the hostname
|
||||
and port to which messages will be sent through the socket, which
|
||||
ensures that the socket's protocol family is consistent with the
|
||||
destination. Alternately, the arguments might be the same as for
|
||||
a future call to @scheme[udp-bind!], which ensures that the
|
||||
socket's protocol family is consistent with the binding. If
|
||||
neither @scheme[family-hostname] nor @scheme[family-port-no] is
|
||||
non-@scheme[#f], then the socket's protocol family is IPv4.}
|
||||
|
||||
@defproc[(udp-bind! [udp-socket udp?]
|
||||
[hostname-string (or/c string? false/c)]
|
||||
[port-no (and/c nonnegative-exact-integer?
|
||||
(integer-in 1 65535))])
|
||||
void?]{
|
||||
|
||||
Binds an unbound @scheme[udp-socket] to the local port number
|
||||
@scheme[port-no].
|
||||
|
||||
If @scheme[hostname-string] is @scheme[#f], then the socket
|
||||
accepts connections to all of the listening machine's IP
|
||||
addresses at @scheme[port-no]. Otherwise, the socket accepts
|
||||
connections only at the IP address associated with the given
|
||||
name. For example, providing @scheme["127.0.0.1"] as
|
||||
@scheme[hostname-string] typically creates a listener that
|
||||
accepts only connections to @scheme["127.0.0.1"] from the local
|
||||
machine.
|
||||
|
||||
A socket cannot receive datagrams until it is bound to a local address
|
||||
and port. If a socket is not bound before it is used with a sending
|
||||
procedure @scheme[udp-send], @scheme[udp-send-to], etc., the sending
|
||||
procedure binds the socket to a random local port. Similarly, if an
|
||||
event from @scheme[udp-send-evt] or @scheme[udp-send-to-evt] is chosen
|
||||
for a synchronization (see @secref["mz:sync"]), the socket is bound;
|
||||
if the event is not chosen, the socket may or may not become
|
||||
bound. The binding of a bound socket cannot be changed.
|
||||
|
||||
If @scheme[udp-socket] is already bound or closed, the
|
||||
@exnraise[exn:fail:network].}
|
||||
|
||||
|
||||
@defproc[(udp-connect! [udp-socket udp?]
|
||||
[hostname-string (or/c string? false/c)]
|
||||
[port-no (or/c (and/c nonnegative-exact-integer?
|
||||
(integer-in 1 65535))
|
||||
false/c)])
|
||||
void?]{
|
||||
|
||||
Connects the socket to the indicated remote address and port if
|
||||
@scheme[hostname-string] is a string and @scheme[port-no] is an exact
|
||||
integer.
|
||||
|
||||
If @scheme[hostname-string] is @scheme[#f], then @scheme[port-no] also
|
||||
must be @scheme[#f], and the port is disconnected (if connected). If
|
||||
one of @scheme[hostname-string] or @scheme[port-no] is @scheme[#f] and
|
||||
the other is not, the @exnraise[exn:fail:contract].
|
||||
|
||||
A connected socket can be used with @scheme[udp-send] (not
|
||||
@scheme[udp-send-to]), and it accepts datagrams only from the
|
||||
connected address and port. A socket need not be connected to receive
|
||||
datagrams. A socket can be connected, re-connected, and disconnected
|
||||
any number of times.
|
||||
|
||||
If @scheme[udp-socket] is closed, the @exnraise[exn:fail:network].}
|
||||
|
||||
|
||||
@defproc[(udp-send-to [udp-socket udp?]
|
||||
[hostname string?]
|
||||
[port-no (and/c nonnegative-exact-integer?
|
||||
(integer-in 1 65535))]
|
||||
[bstr bytes?]
|
||||
[start-pos nonnegative-exact-integer? 0]
|
||||
[end-pos nonnegative-exact-integer? (bytes-length bstr)])
|
||||
void]{
|
||||
|
||||
Sends @scheme[(subbytes bytes start-pos end-pos)] as a datagram from
|
||||
the unconnected @scheme[udp-socket] to the socket at the remote
|
||||
machine @scheme[hostname-address] on the port @scheme[port-no]. The
|
||||
@scheme[udp-socket] need not be bound or connected; if it is not
|
||||
bound, @scheme[udp-send-to] binds it to a random local port. If the
|
||||
socket's outgoing datagram queue is too full to support the send,
|
||||
@scheme[udp-send-to] blocks until the datagram can be queued.
|
||||
|
||||
If @scheme[start-pos] is greater than the length of @scheme[bstr], or
|
||||
if @scheme[end-pos] is less than @scheme[start-pos] or greater than
|
||||
the length of @scheme[bstr], the @exnraise[exn:fail:contract].
|
||||
|
||||
If @scheme[udp-socket] is closed or connected, the
|
||||
@exnraise[exn:fail:network].}
|
||||
|
||||
@defproc[(udp-send [udp-socket udp?]
|
||||
[bstr bytes?]
|
||||
[start-pos nonnegative-exact-integer? 0]
|
||||
[end-pos nonnegative-exact-integer? (bytes-length bstr)])
|
||||
void]{
|
||||
|
||||
Like @scheme[udp-send-to], except that @scheme[udp-socket] must be
|
||||
connected, and the datagram goes to the connection target. If
|
||||
@scheme[udp-socket] is closed or unconnected, the
|
||||
@exnraise[exn:fail:network].}
|
||||
|
||||
@defproc[(udp-send-to* [udp-socket udp?]
|
||||
[hostname string?]
|
||||
[port-no (and/c nonnegative-exact-integer?
|
||||
(integer-in 1 65535))]
|
||||
[bstr bytes?]
|
||||
[start-pos nonnegative-exact-integer? 0]
|
||||
[end-pos nonnegative-exact-integer? (bytes-length bstr)])
|
||||
boolean?]{
|
||||
|
||||
Like @scheme[udp-send-to], but never blocks; if the socket's outgoing
|
||||
queue is too full to support the send, @scheme[#f] is returned,
|
||||
otherwise the datagram is queued and the result is @scheme[#t].}
|
||||
|
||||
@defproc[(udp-send* [udp-socket udp?]
|
||||
[bstr bytes?]
|
||||
[start-pos nonnegative-exact-integer? 0]
|
||||
[end-pos nonnegative-exact-integer? (bytes-length bstr)])
|
||||
boolean?]{
|
||||
|
||||
Like @scheme[udp-send], except that (like @scheme[udp-send-to]) it
|
||||
never blocks and returns @scheme[#f] or @scheme[#t].}
|
||||
|
||||
@defproc[(udp-send-to/enable-break [udp-socket udp?]
|
||||
[hostname string?]
|
||||
[port-no (and/c nonnegative-exact-integer?
|
||||
(integer-in 1 65535))]
|
||||
[bstr bytes?]
|
||||
[start-pos nonnegative-exact-integer? 0]
|
||||
[end-pos nonnegative-exact-integer? (bytes-length bstr)])
|
||||
void]{
|
||||
|
||||
Like @scheme[udp-send-to], but breaking is enabled (see
|
||||
@secref["mz:breakhandler"]) while trying to send the datagram. If
|
||||
breaking is disabled when @scheme[udp-send-to/enable-break] is called,
|
||||
then either the datagram is sent or the @scheme[exn:break] exception
|
||||
is raised, but not both.}
|
||||
|
||||
|
||||
@defproc[(udp-send/enable-break [udp-socket udp?]
|
||||
[bstr bytes?]
|
||||
[start-pos nonnegative-exact-integer? 0]
|
||||
[end-pos nonnegative-exact-integer? (bytes-length bstr)])
|
||||
void]{
|
||||
|
||||
Like @scheme[udp-send], except that breaks are enabled like
|
||||
@scheme[udp-send-to/enable-break].}
|
||||
|
||||
|
||||
@defproc[(udp-receive! [udp-socket udp?]
|
||||
[bstr (and/c bytes? (not immutable?))]
|
||||
[start-pos nonnegative-exact-integer? 0]
|
||||
[end-pos nonnegative-exact-integer? (bytes-length bstr)])
|
||||
(values nonnegative-exact-integer?
|
||||
string?
|
||||
(integer-in 1 65535))]{
|
||||
|
||||
Accepts up to @math{@scheme[end-pos]-@scheme[start-pos]} bytes of
|
||||
@scheme[udp-socket]'s next incoming datagram into @scheme[bstr],
|
||||
writing the datagram bytes starting at position @scheme[start-pos]
|
||||
within @scheme[bstr]. The @scheme[udp-socket] must be bound to a local
|
||||
address and port (but need not be connected). If no incoming datagram
|
||||
is immediately available, @scheme[udp-receive!] blocks until one is
|
||||
available.
|
||||
|
||||
Three values are returned: the number of received bytes (between
|
||||
@scheme[0] and @math{@scheme[end-pos]-@scheme[start-pos]}, a hostname
|
||||
string indicating the source address of the datagram, and an integer
|
||||
indicating the source port of the datagram. If the received datagram
|
||||
is longer than @math{@scheme[end-pos]-@scheme[start-pos]} bytes, the
|
||||
remainder is discarded.
|
||||
|
||||
If @scheme[start-pos] is greater than the length of @scheme[bstr], or
|
||||
if @scheme[end-pos] is less than @scheme[start-pos] or greater than
|
||||
the length of @scheme[bstr], the @exnraise[exn:fail:contract].}
|
||||
|
||||
@defproc[(udp-receive!* [udp-socket udp?]
|
||||
[bstr (and/c bytes? (not immutable?))]
|
||||
[start-pos nonnegative-exact-integer? 0]
|
||||
[end-pos nonnegative-exact-integer? (bytes-length bstr)])
|
||||
(values (or/c nonnegative-exact-integer? false/c)
|
||||
(or/c string? false/c)
|
||||
(or/c (integer-in 1 65535) false/c))]{
|
||||
|
||||
Like @scheme[udp-receive!], except that it never blocks. If no
|
||||
datagram is available, the three result values are all @scheme[#f].}
|
||||
|
||||
@defproc[(udp-receive!/enable-break [udp-socket udp?]
|
||||
[bstr (and/c bytes? (not immutable?))]
|
||||
[start-pos nonnegative-exact-integer? 0]
|
||||
[end-pos nonnegative-exact-integer? (bytes-length bstr)])
|
||||
(values nonnegative-exact-integer?
|
||||
string?
|
||||
(integer-in 1 65535))]{
|
||||
|
||||
Like @scheme[udp-receive!], but breaking is enabled (see
|
||||
@secref["mz:breakhandler"]) while trying to receive the datagram. If
|
||||
breaking is disabled when @scheme[udp-receive!/enable-break] is
|
||||
called, then either a datagram is received or the @scheme[exn:break]
|
||||
exception is raised, but not both.}
|
||||
|
||||
|
||||
@defproc[(udp-close [udp-socket udp?]) void?]{
|
||||
|
||||
Closes @scheme[udp-socket], discarding unreceived datagrams. If the
|
||||
socket is already closed, the @exnraise[exn:fail:network].}
|
||||
|
||||
|
||||
@defproc[(udp? [v any/c]) boolean?]{
|
||||
|
||||
Returns @scheme[#t] if @scheme[v] is a socket created by
|
||||
@scheme[udp-open-socket], @scheme[#f] otherwise.}
|
||||
|
||||
|
||||
@defproc[(udp-bound? [udp-socket udp?]) boolean?]{
|
||||
|
||||
Returns @scheme[#t] if @scheme[udp-socket] is bound to a local address
|
||||
and port, @scheme[#f] otherwise.}
|
||||
|
||||
|
||||
@defproc[(udp-connected? [udp-socket udp?]) boolean?]{
|
||||
|
||||
Returns @scheme[#t] if @scheme[udp-socket] is connected to a remote
|
||||
address and port, @scheme[#f] otherwise.}
|
||||
|
||||
|
||||
@defproc[(udp-send-ready-evt [udp-socket udp?]) evt?]{
|
||||
|
||||
Returns a @tech{synchronizable event} (see @secref["mz:sync"]) that is
|
||||
in a blocking state when @scheme[udp-send-to] on @scheme[udp-socket]
|
||||
would block.}
|
||||
|
||||
|
||||
@defproc[(udp-receive-ready-evt [udp-socket udp?]) evt?]{
|
||||
|
||||
Returns a @tech{synchronizable event} (see @secref["mz:sync"]) that is
|
||||
in a blocking state when @scheme[udp-receive!] on @scheme[udp-socket]
|
||||
would block.}
|
||||
|
||||
@defproc[(udp-send-to-evt [udp-socket udp?]
|
||||
[hostname string?]
|
||||
[port-no (and/c nonnegative-exact-integer?
|
||||
(integer-in 1 65535))]
|
||||
[bstr bytes?]
|
||||
[start-pos nonnegative-exact-integer? 0]
|
||||
[end-pos nonnegative-exact-integer? (bytes-length bstr)])
|
||||
evt?]{
|
||||
|
||||
Returns a @tech{synchronizable event}. The event is in a blocking
|
||||
state when @scheme[udp-send-to] on @scheme[udp-socket] would
|
||||
block. Otherwise, if the event is chosen in a synchronization, data is
|
||||
sent as for @scheme[(udp-send-to udp-socket hostname-address port-no
|
||||
bstr start-pos end-pos)], and the synchronization result is
|
||||
@|void-const|. (No bytes are sent if the event is not chosen.)}
|
||||
|
||||
|
||||
@defproc[(udp-send-evt [udp-socket udp?]
|
||||
[bstr bytes?]
|
||||
[start-pos nonnegative-exact-integer? 0]
|
||||
[end-pos nonnegative-exact-integer? (bytes-length bstr)])
|
||||
evt?]{
|
||||
|
||||
Returns a @tech{synchronizable event}. The event is in a blocking
|
||||
state when @scheme[udp-send] on @scheme[udp-socket] would
|
||||
block. Otherwise, if the event is chosen in a synchronization, data is
|
||||
sent as for @scheme[(udp-send-to udp-socket bstr start-pos end-pos)],
|
||||
and the synchronization result is @|void-const|. (No bytes are sent if
|
||||
the event is not chosen.) If @scheme[udp-socket] is closed or
|
||||
unconnected, the @exnraise[exn:fail:network] during a synchronization
|
||||
attempt.}
|
||||
|
||||
@defproc[(udp-receive!-evt [udp-socket udp?]
|
||||
[bstr (and/c bytes? (not immutable?))]
|
||||
[start-pos nonnegative-exact-integer? 0]
|
||||
[end-pos nonnegative-exact-integer? (bytes-length bstr)])
|
||||
evt?]{
|
||||
|
||||
Returns a @tech{synchronizable event}. The event is in a blocking
|
||||
state when @scheme[udp-receive] on @scheme[udp-socket] would
|
||||
block. Otherwise, if the event is chosen in a synchronization, data is
|
||||
received into @scheme[bstr] as for @scheme[(udp-receive! udp-socket
|
||||
bytes start-pos end-pos)], and the synchronization result is a list of
|
||||
three values, corresponding to the three results from
|
||||
@scheme[udp-receive!]. (No bytes are received and the @scheme[bstr]
|
||||
content is not modified if the event is not chosen.)}
|
|
@ -5,4 +5,6 @@
|
|||
|
||||
@local-table-of-contents[]
|
||||
|
||||
@include-section["platform-paths.scrbl"]
|
||||
@include-section["paths.scrbl"]
|
||||
@include-section["filesystem.scrbl"]
|
||||
@include-section["networking.scrbl"]
|
||||
|
|
482
collects/scribblings/reference/paths.scrbl
Normal file
482
collects/scribblings/reference/paths.scrbl
Normal file
|
@ -0,0 +1,482 @@
|
|||
#reader(lib "docreader.ss" "scribble")
|
||||
@require["mz.ss"]
|
||||
|
||||
@title[#:tag "mz:pathutils" #:style 'toc]{Paths}
|
||||
|
||||
When a Scheme procedure takes a filesystem path as an argument, the
|
||||
path can be provided either as a string or as an instance of the
|
||||
@deftech{path} datatype. If a string is provided, it is converted to a
|
||||
path using @scheme[string->path]. A Scheme procedure that generates a
|
||||
filesystem path always generates a @tech{path} value.
|
||||
|
||||
By default, paths are created and manipulated for the current
|
||||
platform, but procedures that merely manipulate paths (without using
|
||||
the filesystem) can manipulate paths using conventions for other
|
||||
supported platforms. The @scheme[bytes->path] procedure accepts an
|
||||
optional argument that indicates the platform for the path, either
|
||||
@scheme['unix] or @scheme['windows]. For other functions, such as
|
||||
@scheme[build-path] or @scheme[simplify-path], the behavior is
|
||||
sensitive to the kind of path that is supplied. Unless otherwise
|
||||
specified, a procedure that requires a path accepts only paths for the
|
||||
current platform.
|
||||
|
||||
Two @tech{path} values are @scheme[equal?] when they are use the same
|
||||
convention type and when their byte-string representations are
|
||||
@scheme[equal?]. A path string (or byte string) cannot be empty, and
|
||||
it cannot contain a nul character or byte. When an empty string or a
|
||||
string containing nul is provided as a path to any procedure except
|
||||
@scheme[absolute-path?], @scheme[relative-path?], or
|
||||
@scheme[complete-path?], the @exnraise[exn:fail:contract].
|
||||
|
||||
Most Scheme primitives that accept paths first @deftech{path-expand}
|
||||
the path before using it. Procedures that build paths or merely check
|
||||
the form of a path do not perform this expansion, with the exception
|
||||
of @scheme[simplify-path] for Windows paths. For more information
|
||||
about path expansion and other platform-specific details, see
|
||||
@secref["mz:unixpaths"] for @|AllUnix| paths and
|
||||
@secref["mz:windowspaths"] for Windows paths.
|
||||
|
||||
@;------------------------------------------------------------------------
|
||||
@section{Manipulating Paths}
|
||||
|
||||
@defproc[(path? [v any/c]) boolean?]{
|
||||
|
||||
Returns @scheme[#t] if @scheme[v] is a path value for the current
|
||||
platform (not a string, and not a path for a different platform),
|
||||
@scheme[#f] otherwise.}
|
||||
|
||||
@defproc[(path-string? [v any/c]) boolean?]{
|
||||
|
||||
Return @scheme[#t] if @scheme[v] is either a path value for the
|
||||
current platform or a non-empty string without nul characters,
|
||||
@scheme[#f] otherwise.}
|
||||
|
||||
@defproc[(path-for-some-system? [v any/c]) boolean?]{
|
||||
|
||||
Returns @scheme[#t] if @scheme[v] is a path value for some platform
|
||||
(not a string), @scheme[#f] otherwise.}
|
||||
|
||||
@defproc[(string->path [str string?]) path?]{
|
||||
|
||||
Produces a path whose byte-string name is
|
||||
@scheme[(string->bytes/locale string (char->integer #\?))].
|
||||
|
||||
Beware that the current locale might not encode every string, in which
|
||||
case @scheme[string->path] can produce the same path for different
|
||||
@scheme[str]s. See also @scheme[string->path-element], which should be
|
||||
used instead of @scheme[string->path] when a string represents a
|
||||
single path element.}
|
||||
|
||||
@defproc[(bytes->path [bstr bytes?]
|
||||
[type (one-of/c 'unix 'windows) (system-path-convention-type)])
|
||||
path?]{
|
||||
|
||||
Produces a path (for some platform) whose byte-string name is
|
||||
@scheme[bstr]. The optional @scheme[type] specifies the convention to
|
||||
use for the path.
|
||||
|
||||
For converting relative path elements from literals, use instead
|
||||
@scheme[bytes->path-element], which applies a suitable encoding for
|
||||
individual elements.}
|
||||
|
||||
@defproc[(path->string [path path?]) string?]{
|
||||
|
||||
Produces a string that represents @scheme[path] by decoding
|
||||
@scheme[path]'s byte-string name using the current locale's encoding;
|
||||
@litchar{?} is used in the result string where encoding fails, and if
|
||||
the encoding result is the empty string, then the result is
|
||||
@scheme["?"].
|
||||
|
||||
The resulting string is suitable for displaying to a user,
|
||||
string-ordering comparisons, etc., but it is not suitable for
|
||||
re-creating a path (possibly modified) via @scheme[string->path],
|
||||
since decoding and re-encoding the path's byte string may lose
|
||||
information.
|
||||
|
||||
Furthermore, for display and sorting based on individual path elements
|
||||
(such as pathless file names), use @scheme[path-element->string],
|
||||
instead, to avoid special encodings use to represent some relative
|
||||
paths. See @secref["mz:windowspaths"] for specific information about
|
||||
the conversion of Windows paths.}
|
||||
|
||||
@defproc[(path->bytes [path path?]) bytes?]{
|
||||
|
||||
Produces @scheme[path]'s byte string representation. No information is
|
||||
lost in this translation, so that @scheme[(bytes->path (path->bytes
|
||||
path) (path-convention-type path))] always produces a path is that is
|
||||
@scheme[equal?] to @scheme[path]. The @scheme[path] argument can be a
|
||||
path for any platform.
|
||||
|
||||
Conversion to and from byte values is useful for marshaling and
|
||||
unmarshaling paths, but manipulating the byte form of a path is
|
||||
generally a mistake. In particular, the byte string may start with a
|
||||
@litchar{\\?\REL} encoding for Windows paths or a @litchar{./~}
|
||||
encoding for @|AllUnix| paths. Instead of @scheme[path->bytes], use
|
||||
@scheme[split-path] and @scheme[path-element->bytes] to manipulate
|
||||
individual path elements.}
|
||||
|
||||
@defproc[(string->path-element [str string?]) path?]{
|
||||
|
||||
Like @scheme[string->path], except that @scheme[str] corresponds to a
|
||||
single relative element in a path, and it is encoded as necessary to
|
||||
convert it to a path. See @secref["mz:unixpaths"] for more information
|
||||
on the conversion for @|AllUnix| paths, and see
|
||||
@secref["mz:windowspaths"] for more information on the conversion for
|
||||
Windows paths.
|
||||
|
||||
If @scheme[str] does not correspond to any path element
|
||||
(e.g., it is an absolute path, or it can be split), or if it
|
||||
corresponds to an up-directory or same-directory indicator under
|
||||
@|AllUnix|, then @exnraise[exn:fail:contract].
|
||||
|
||||
As for @scheme[path->string], information can be lost from
|
||||
@scheme[str] in the locale-specific conversion to a path.}
|
||||
|
||||
|
||||
@defproc[(bytes->path-element [bstr bytes?]
|
||||
[type (one-of/c 'unix 'windows) (system-path-convention-type)])
|
||||
path?]{
|
||||
|
||||
Like @scheme[bytes->path], except that @scheme[bstr] corresponds to a
|
||||
single relative element in a path. In terms of conversions and
|
||||
restrictions on @scheme[bstr], @scheme[bytes->path-element] is like
|
||||
@scheme[string->path-element].
|
||||
|
||||
The @scheme[bytes->path-element] procedure is generally the best
|
||||
choice for reconstructing a path based on another path (where the
|
||||
other path is deconstructed with @scheme[split-path] and
|
||||
@scheme[path-element->bytes]) when ASCII-level manipulation of path
|
||||
elements is necessary.}
|
||||
|
||||
@defproc[(path-element->string [path path?]) string?]{
|
||||
|
||||
Like @scheme[path->string], except any encoding prefix is removed. See
|
||||
@secref["mz:unixpaths"] for more information on the conversion for
|
||||
@|AllUnix| paths, and see @secref["mz:windowspaths"] for more
|
||||
information on the conversion for Windows paths.
|
||||
In addition, trailing path separators are removed, as by
|
||||
@scheme[split-path].
|
||||
|
||||
The @scheme[path] argument must be such that @scheme[split-path]
|
||||
applied to @scheme[path] would return @scheme['relative] as its first
|
||||
result and a path as its second result, otherwise the
|
||||
@exnraise[exn:fail:contract].
|
||||
|
||||
The @scheme[path-element->string] procedure is generally the best
|
||||
choice for presenting a pathless file or directory name to a user.}
|
||||
|
||||
@defproc[(path-element->bytes [path path-string?]) bytes?]{
|
||||
|
||||
Like @scheme[path->bytes], except that any encoding prefix is removed,
|
||||
etc., as for @scheme[path-element->string].
|
||||
|
||||
For any reasonable locale, consecutive ASCII characters in the printed
|
||||
form of @scheme[path] are mapped to consecutive byte values that match
|
||||
each character's code-point value, and a leading or trailing ASCII
|
||||
character is mapped to a leading or trailing byte, respectively. The
|
||||
@scheme[path] argument can be a path for any platform.
|
||||
|
||||
The @scheme[path-element->bytes] procedure is generally the right
|
||||
choice (in combination with @scheme[split-path]) for extracting the
|
||||
content of a path to manipulate it at the ASCII level (then
|
||||
reassembling the result with @scheme[bytes->path-element] and
|
||||
@scheme[build-path]).}
|
||||
|
||||
|
||||
@defproc[(path-convention-type [path path?])
|
||||
(one-of 'unix 'windows)]{
|
||||
|
||||
Accepts a path value (not a string) and returns its convention
|
||||
type.}
|
||||
|
||||
|
||||
@defproc[(system-path-convention-type)
|
||||
(one-of 'unix 'windows)]{
|
||||
|
||||
Returns the path convention type of the current platform:
|
||||
@scheme['unix] for @|AllUnix|, @scheme['windows] for Windows.}
|
||||
|
||||
|
||||
@defproc[(build-path [base path-string?]
|
||||
[sub (or/c path-string?
|
||||
(one-of/c 'up 'same))] ...)
|
||||
path?]{
|
||||
|
||||
Creates a path given a base path and any number of sub-path
|
||||
extensions. If @scheme[base] is an absolute path, the result is an
|
||||
absolute path; if @scheme[base] is a relative path, the result is a
|
||||
relative path.
|
||||
|
||||
Each @scheme[sub] must be either a relative path, the symbol
|
||||
@scheme['up] (indicating the relative parent directory), or the symbol
|
||||
@scheme['same] (indicating the relative current directory). For
|
||||
Windows paths, if @scheme[base] is a drive specification (with or
|
||||
without a trailing slash) the first @scheme[sub] can be an absolute
|
||||
(driveless) path. For all platforms, the last @scheme[sub] can be a
|
||||
filename.
|
||||
|
||||
The @scheme[base] and @scheme[sub-paths] arguments can be paths for
|
||||
any platform. The platform for the resulting path is inferred from the
|
||||
@scheme[base] and @scheme[sub] arguments, where string arguments imply
|
||||
a path for the current platform. If different arguments are for
|
||||
different platforms, the @exnraise[exn:fail:contract]. If no argument
|
||||
implies a platform (i.e., all are @scheme['up] or @scheme['same]), the
|
||||
generated path is for the current platform.
|
||||
|
||||
Each @scheme[sub] and @scheme[base] can optionally end in a directory
|
||||
separator. If the last @scheme[sub] ends in a separator, it is
|
||||
included in the resulting path.
|
||||
|
||||
If @scheme[base] or @scheme[sub] is an illegal path string (because it
|
||||
is empty or contains a nul character), the
|
||||
@exnraise[exn:fail:contract].
|
||||
|
||||
The @scheme[build-path] procedure builds a path @italic{without}
|
||||
checking the validity of the path or accessing the filesystem.
|
||||
|
||||
See @secref["mz:unixpaths"] for more information on the construction
|
||||
of @|AllUnix| paths, and see @secref["mz:windowspaths"] for more
|
||||
information on the construction of Windows paths.
|
||||
|
||||
The following examples assume that the current directory is
|
||||
\File{/home/joeuser} for Unix examples and \File{C:\Joe's Files} for
|
||||
Windows examples.
|
||||
|
||||
@schemeblock[
|
||||
(define p1 (build-path (current-directory) "src" "scheme"))
|
||||
(code:comment #, @t{Unix: @scheme[p1] is @scheme["/home/joeuser/src/scheme"]})
|
||||
(code:comment #, @t{Windows: @scheme[p1] is @scheme["C:\\Joe's Files\\src\\scheme"]})
|
||||
(define p2 (build-path 'up 'up "docs" "Scheme"))
|
||||
(code:comment #, @t{Unix: @scheme[p2] is @scheme["../../docs/Scheme"]})
|
||||
(code:comment #, @t{Windows: @scheme[p2] is @scheme["..\\..\\docs\\Scheme"]})
|
||||
(build-path p2 p1)
|
||||
(code:comment #, @t{Unix and Windows: raises @scheme[exn:fail:contract]; @scheme[p1] is absolute})
|
||||
(build-path p1 p2)
|
||||
(code:comment #, @t{Unix: is @scheme["/home/joeuser/src/scheme/../../docs/Scheme"]})
|
||||
(code:comment #, @t{Windows: is @scheme["C:\\Joe's Files\\src\\scheme\\..\\..\\docs\\Scheme"]})
|
||||
]}
|
||||
|
||||
|
||||
@defproc[(build-path/convention-type [type (one-of/c 'unix 'windows)]
|
||||
[base path-string?]
|
||||
[sub (or/c path-string?
|
||||
(one-of/c 'up 'same))] ...)
|
||||
path?]{
|
||||
|
||||
Like @scheme[build-path], except a path convention type is specified
|
||||
explicitly.}
|
||||
|
||||
@defproc[(absolute-path? [path path-string?]) boolean?]{
|
||||
|
||||
Returns @scheme[#t] if @scheme[path] is an absolute path, @scheme[#f]
|
||||
otherwise. The @scheme[path] argument can be a path for any
|
||||
platform. If @scheme[path] is not a legal path string (e.g., it
|
||||
contains a nul character), @scheme[#f] is returned. This procedure
|
||||
does not access the filesystem.}
|
||||
|
||||
|
||||
@defproc[(relative-path? [path path-string?]) boolean?]{
|
||||
|
||||
Returns @scheme[#t] if @scheme[path] is a relative path, @scheme[#f]
|
||||
otherwise. The @scheme[path] argument can be a path for any
|
||||
platform. If @scheme[path] is not a legal path string (e.g., it
|
||||
contains a nul character), @scheme[#f] is returned. This procedure
|
||||
does not access the filesystem.}
|
||||
|
||||
|
||||
@defproc[(complete-path? [path path-string?]) boolean?]{
|
||||
|
||||
Returns @scheme[#t] if @scheme[path] is a completely determined path
|
||||
(@italic{not} relative to a directory or drive), @scheme[#f]
|
||||
otherwise. The @scheme[path] argument can be a path for any
|
||||
platform. Note that for Windows paths, an absolute path can omit the
|
||||
drive specification, in which case the path is neither relative nor
|
||||
complete. If @scheme[path] is not a legal path string (e.g., it
|
||||
contains a nul character), @scheme[#f] is returned.
|
||||
|
||||
This procedure does not access the filesystem.}
|
||||
|
||||
|
||||
@defproc[(path->complete-path [path path-string?]
|
||||
[base path-string? (current-directory)])
|
||||
path?]{
|
||||
|
||||
Returns @scheme[path] as a complete path. If @scheme[path] is already
|
||||
a complete path, it is returned as the result. Otherwise,
|
||||
@scheme[path] is resolved with respect to the complete path
|
||||
@scheme[base]. If @scheme[base] is not a complete path, the
|
||||
@exnraise[exn:fail:contract].
|
||||
|
||||
The @scheme[path] and @scheme[base] arguments can paths for any
|
||||
platform; if they are for different
|
||||
platforms, the @exnraise[exn:fail:contract].
|
||||
|
||||
This procedure does not access the filesystem.}
|
||||
|
||||
|
||||
@defproc[(path->directory-path [path path-string?]) path?]{
|
||||
|
||||
Returns @scheme[path] if @scheme[path] syntactically refers to a
|
||||
directory and ends in a separator, otherwise it returns an extended
|
||||
version of @scheme[path] that specifies a directory and ends with a
|
||||
separator. For example, under @|AllUnix|, the path @file{x/y/}
|
||||
syntactically refers to a directory and ends in a separator, but
|
||||
@file{x/y} would be extended to @file{x/y/}, and @file{x/..} would be
|
||||
extended to @file{x/../}. The @scheme[path] argument can be a path for
|
||||
any platform, and the result will be for the same platform.
|
||||
|
||||
This procedure does not access the filesystem.}
|
||||
|
||||
|
||||
@defproc[(resolve-path [path path-string?]) path?]{
|
||||
|
||||
@tech{Path-expands} @scheme[path] and returns a path that references
|
||||
the same file or directory as @scheme[path]. Under @|AllUnix|, if
|
||||
@scheme[path] is a soft link to another path, then the referenced path
|
||||
is returned (this may be a relative path with respect to the directory
|
||||
owning @scheme[path]), otherwise @scheme[path] is returned (after
|
||||
expansion).}
|
||||
|
||||
|
||||
@defproc[(expand-path [path path-string?]) path]{
|
||||
|
||||
@tech{Path-expands} @scheme[path] (as described at the beginning of
|
||||
this section). The filesystem might be accessed, but the source or
|
||||
expanded path might be a non-existent path.}
|
||||
|
||||
|
||||
@defproc[(simplify-path [path path-string?][use-filesystem? boolean? #t]) path?]{
|
||||
|
||||
Eliminates redundant path separators (except for a single trailing
|
||||
separator), up-directory @litchar{..}, and same-directory @litchar{.}
|
||||
indicators in @scheme[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 @scheme[path].
|
||||
|
||||
In general, the pathname is normalized as much as possible --- without
|
||||
consulting the filesystem if @scheme[use-filesystem?] is @scheme[#f],
|
||||
and (under Windows) without changing the case of letters within the
|
||||
path. If @scheme[path] syntactically refers to a directory, the
|
||||
result ends with a directory separator.
|
||||
|
||||
When @scheme[path] is simplified and @scheme[use-filesystem?] is true
|
||||
(the default), a complete path is returned; if @scheme[path] is
|
||||
relative, it is resolved with respect to the current directory, and
|
||||
up-directory indicators are removed taking into account soft links (so
|
||||
that the resulting path refers to the same directory as before).
|
||||
|
||||
When @scheme[use-filesystem?] is @scheme[#f], up-directory indicators
|
||||
are removed by deleting a preceding path element, and the result can
|
||||
be a relative path with up-directory indicators remaining at the
|
||||
beginning of the path or, for @|AllUnix| paths, after an initial path
|
||||
element that starts with @litchar{~}; otherwise, up-directory
|
||||
indicators are dropped when they refer to the parent of a root
|
||||
directory. Similarly, the result can be the same as
|
||||
@scheme[(build-path 'same)] (but with a trailing separator) if
|
||||
eliminating up-directory indicators leaves only same-directory
|
||||
indicators, and the result can start with a same-directory indicator
|
||||
for @|AllUnix| paths if eliminating it would make the result start
|
||||
with a @litchar{~}.
|
||||
|
||||
The @scheme[path] argument can be a path for any platform when
|
||||
@scheme[use-filesystem?] is @scheme[#f], and the resulting path is for
|
||||
the same platform.
|
||||
|
||||
The filesystem might be accessed when @scheme[use-filesystem?] is
|
||||
true, but the source or expanded path might be a non-existent path. If
|
||||
@scheme[path] cannot be simplified due to a cycle of links, the
|
||||
@exnraise[exn:fail:filesystem] (but a successfully simplified path may
|
||||
still involve a cycle of links if the cycle did not inhibit the
|
||||
simplification).
|
||||
|
||||
See @secref["mz:unixpaths"] for more information on simplifying
|
||||
@|AllUnix| paths, and see @secref["mz:windowspaths"] for more
|
||||
information on simplifying Windows paths.}
|
||||
|
||||
|
||||
@defproc[(normal-case-path [path path-string?]) path?]{
|
||||
|
||||
Returns @scheme[path] with ``normalized'' case letters. For @|AllUnix|
|
||||
paths, this procedure always returns the input path, because
|
||||
filesystems for these platforms can be case-sensitive. For Windows
|
||||
paths, if @scheme[path] does not start @litchar["\\\\?\\"], the
|
||||
resulting string uses only lowercase letters, based on the current
|
||||
locale. In addition, for Windows paths when the path does not start
|
||||
@litchar["\\\\?\\"], all @litchar{/}s are converted to
|
||||
@litchar["\\"]s, and trailing spaces and @litchar{.}s are removed.
|
||||
|
||||
The @scheme[path] argument can be a path for any platform, but beware
|
||||
that local-sensitive decoding and conversion of the path may be
|
||||
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?
|
||||
(one-of/c 'relative #f))
|
||||
(or/c path?
|
||||
(one-of/c 'up 'same))
|
||||
boolean?)]{
|
||||
|
||||
Deconstructs @scheme[path] into a smaller path and an immediate
|
||||
directory or file name. Three values are returned:
|
||||
|
||||
@itemize{
|
||||
|
||||
@item{@scheme[base] is either
|
||||
|
||||
@itemize{
|
||||
@item{a path,}
|
||||
@item{@scheme['relative] if @scheme[path] is an immediate relative directory
|
||||
or filename, or}
|
||||
@item{@scheme[#f] if @scheme[path] is a root directory.}
|
||||
}}
|
||||
|
||||
@item{@scheme[name] is either
|
||||
@itemize{
|
||||
@item{a directory-name path,}
|
||||
@item{a filename,}
|
||||
@item{@scheme['up] if the last part of @scheme[path] specifies the parent
|
||||
directory of the preceding path (e.g., @litchar{..} under Unix), or}
|
||||
@item{@scheme['same] if the last part of @scheme[path] specifies the
|
||||
same directory as the preceding path (e.g., @litchar{.} under Unix).}
|
||||
}}
|
||||
|
||||
@item{@scheme[must-be-dir?] is @scheme[#t] if @scheme[path] explicitly
|
||||
specifies a directory (e.g., with a trailing separator), @scheme[#f]
|
||||
otherwise. Note that @scheme[must-be-dir?] does not specify whether
|
||||
@scheme[name] is actually a directory or not, but whether @scheme[path]
|
||||
syntactically specifies a directory.}
|
||||
|
||||
}
|
||||
|
||||
Compared to @scheme[path], redundant separators (if any) are removed
|
||||
in the result @scheme[base] and @scheme[name]. If @scheme[base] is
|
||||
@scheme[#f], then @scheme[name] cannot be @scheme['up] or
|
||||
@scheme['same]. The @scheme[path] argument can be a path for any
|
||||
platform, and resulting paths for the same platform.
|
||||
|
||||
This procedure does not access the filesystem.
|
||||
|
||||
See @secref["mz:unixpaths"] for more information on splitting
|
||||
@|AllUnix| paths, and see @secref["mz:windowspaths"] for more
|
||||
information on splitting Windows paths.}
|
||||
|
||||
|
||||
@defproc[(path-replace-suffix [path path-string?]
|
||||
[suffix (or/c string? bytes?)])
|
||||
path?]{
|
||||
|
||||
Returns a path that is the same as @scheme[path], except that the
|
||||
suffix for the last element of the path is changed to
|
||||
@scheme[suffix]. If the last element of @scheme[path] has no suffix,
|
||||
then @scheme[suffix] is added to the path. A suffix is defined as a
|
||||
period followed by any number of non-period characters/bytes at the
|
||||
end of the path element. The @scheme[path] argument can be a path for
|
||||
any platform, and the result is for the same platform. If
|
||||
@scheme[path] represents a root, the @exnraise[exn:fail:contract].}
|
||||
|
||||
@;------------------------------------------------------------------------
|
||||
@include-section["unix-paths.scrbl"]
|
||||
@include-section["windows-paths.scrbl"]
|
|
@ -727,8 +727,7 @@ the result is a syntax object in @scheme[read] mode, then it is
|
|||
converted to a datum using @scheme[syntax-object->datum]; if the
|
||||
result is not a syntax object in @scheme[read-syntax] mode, then it is
|
||||
converted to one using @scheme[datum->syntax-object]. See also
|
||||
@secref["special-comments"] and @secref["recursive-reads"] for
|
||||
information on special-comment results and recursive reads.
|
||||
@secref["mz:reader-procs"] for information on the procedure's results.
|
||||
|
||||
If the @scheme[read-accept-reader] @tech{parameter} is set to
|
||||
@scheme[#f], then if the reader encounters @litchar{#reader}, the
|
||||
|
|
|
@ -2,7 +2,22 @@
|
|||
@require[(lib "bnf.ss" "scribble")]
|
||||
@require["mz.ss"]
|
||||
|
||||
@title[#:tag "mz:readtables"]{Readtables}
|
||||
@title[#:style 'toc]{Reader Extension}
|
||||
|
||||
Scheme's reader can be extended in three ways: through a reader-macro
|
||||
procedure in a readtable (see @secref["mz:readtables"]), through a
|
||||
@litchar{#reader} form (see @secref["mz:parse-reader"]), or through a
|
||||
custom-port byte reader that returns a ``special'' result procedure
|
||||
(see @secref["mz:customport"]). All three kinds of @deftech{reader
|
||||
extension procedures} accept similar arguments, and their results are
|
||||
treated in the same way by @scheme[read] and @scheme[read-syntax] (or,
|
||||
more precisely, by the default read handler; see
|
||||
@scheme[port-read-handler]).
|
||||
|
||||
@local-table-of-contents[]
|
||||
|
||||
@;------------------------------------------------------------------------
|
||||
@section[#:tag "mz:readtables"]{Readtables}
|
||||
|
||||
The dispatch table in @secref["mz:default-readtable-dispatch"]
|
||||
corresponds to the default @deftech{readtable}. By creating a new
|
||||
|
@ -119,8 +134,16 @@ multiple non-@scheme['dispatch-macro] mappings are provided for a
|
|||
single @scheme[_char], all but the last one are ignored.
|
||||
|
||||
A reader macro @scheme[_proc] must accept six arguments, and it can
|
||||
optionally accept two arguments. See @secref["mz:reader-procs"] for
|
||||
information on the procedure's arguments and results.
|
||||
optionally accept two arguments. The first two arguments are always
|
||||
the character that triggered the reader macro and the input port for
|
||||
reading. When the reader macro is triggered by @scheme[read-syntax]
|
||||
(or @scheme[read-syntax/recursive]), the procedure is passed four
|
||||
additional arguments that represent a source location. When the reader
|
||||
macro is triggered by @scheme[read] (or @scheme[read/recursive]), the
|
||||
procedure is passed only two arguments if it accepts two arguments,
|
||||
otherwise it is passed six arguments where the last four are all
|
||||
@scheme[#f]. See @secref["mz:reader-procs"] for information on the
|
||||
procedure's results.
|
||||
|
||||
A reader macro normally reads characters from the given input port to
|
||||
produce a value to be used as the ``reader macro-expansion'' of the
|
||||
|
@ -290,4 +313,74 @@ character and the @scheme[#f] readtable.}
|
|||
#\_ #\space #f))
|
||||
(parameterize ([current-readtable tuple-readtable+])
|
||||
(read (open-input-string "< * 1 __,__ 2 __,__ * \"a\" * >")))
|
||||
]]
|
||||
]]
|
||||
|
||||
@;------------------------------------------------------------------------
|
||||
@section[#:tag "mz:reader-procs"]{Reader-Extension Procedures}
|
||||
|
||||
Calls to @techlink{reader extension procedures} can be triggered
|
||||
through @scheme[read], @scheme[read/recursive], @scheme[read-syntax],
|
||||
or @scheme[read-honu-syntax]. In addition, a special-read procedure
|
||||
can be triggered by calls to @scheme[read-honu],
|
||||
@scheme[read-honu/recursive], @scheme[read-honu-syntax],
|
||||
@scheme[read-honu-syntax/recursive], @scheme[read-char-or-special], or
|
||||
by the context of @scheme[read-bytes-avail!],
|
||||
@scheme[read-bytes-avail!*], @scheme[read-bytes-avail!], and
|
||||
@scheme[peek-bytes-avail!*].
|
||||
|
||||
Optional arities for reader-macro and special-result procedures allow
|
||||
them to distinguish reads via @scheme[read], @|etc| from reads via
|
||||
@scheme[read-syntax], @|etc| (where the source value is @scheme[#f] and
|
||||
no other location information is available).
|
||||
|
||||
When a reader-extension procedure is called in syntax-reading mode
|
||||
(via @scheme[read-syntax], @|etc|), it should generally return a syntax
|
||||
object that has no lexical context (e.g., a syntax object created
|
||||
using @scheme[datum->syntax-object] with @scheme[#f] as the first
|
||||
argument and with the given location information as the third
|
||||
argument). Another possible result is a special-comment value (see
|
||||
@secref["mz:special-comments"]). If the procedure's result is not a
|
||||
syntax object and not a special-comment value, it is converted to one
|
||||
using @scheme[datum->syntax-object].
|
||||
|
||||
When a reader-extension procedure is called in non-syntax-reading
|
||||
modes, it should generally not return a syntax object. If a syntax
|
||||
object is returned, it is converted to a plain value using
|
||||
@scheme[syntax-object->datum].
|
||||
|
||||
In either context, when the result from a reader-extension procedure
|
||||
is a special-comment value (see @secref["mz:special-comments"]), then
|
||||
@scheme[read], @scheme[read-syntax], @|etc| treat the value as a
|
||||
delimiting comment and otherwise ignore it.
|
||||
|
||||
Also, in either context, the result may be copied to prevent mutation
|
||||
to pairs, vectors, or boxes before the read result is completed, and
|
||||
to support the construction of graphs with cycles. Mutable pairs,
|
||||
boxes, and vectors are copied, along with any pairs, boxes, or vectors
|
||||
that lead to such mutable values, to placeholders produced by a
|
||||
recursive read (see @scheme[read/recursive]), or to references of a
|
||||
shared value. Graph structure (including cycles) is preserved in the
|
||||
copy.
|
||||
|
||||
@;------------------------------------------------------------------------
|
||||
@section[#:tag "mz:special-comments"]{Special Comments}
|
||||
|
||||
@defproc[(make-special-comment [v any/c]) special-comment?]{
|
||||
|
||||
Creates a special-comment value that encapsulates @scheme[v]. The
|
||||
@scheme[read], @scheme[read-syntax], @|etc| procedures treat values
|
||||
constructed with @scheme[make-special-comment] as delimiting
|
||||
whitespace when returned by a reader-extension procedure (see
|
||||
@secref["mz:reader-procs"]).}
|
||||
|
||||
@defproc[(special-comment? [v any/c]) boolean?]{
|
||||
|
||||
Returns @scheme[#t] if @scheme[v] is the result of
|
||||
@scheme[make-special-comment], @scheme[#f] otherwise.}
|
||||
|
||||
@defproc[(special-comment-value [sc special-comment?]) any]{
|
||||
|
||||
Returns the value encapsulated by the special-comment value
|
||||
@scheme[sc]. This value is never used directly by a reader, but it
|
||||
might be used by the context of a @scheme[read-char-or-special], @|etc|
|
||||
call that detects a special comment.}
|
||||
|
|
60
collects/scribblings/reference/unix-paths.scrbl
Normal file
60
collects/scribblings/reference/unix-paths.scrbl
Normal file
|
@ -0,0 +1,60 @@
|
|||
#reader(lib "docreader.ss" "scribble")
|
||||
@require[(lib "bnf.ss" "scribble")]
|
||||
@require["mz.ss"]
|
||||
|
||||
@title[#:tag "mz:unixpaths"]{@|AllUnix| Paths}
|
||||
|
||||
In @|AllUnix| paths, a @litchar{/} separates elements of the path,
|
||||
@litchar{.} as a path element always means the directory indicated by
|
||||
preceding path, and @litchar{..} as a path element always means the
|
||||
parent of the directory indicated by the preceding path. A path that
|
||||
starts with a @litchar{~} indicates a user's home directory; the
|
||||
username follows the @litchar{~} (before a @litchar{/} or the end of
|
||||
the path), where @litchar{~} by itself indicates the home directory of
|
||||
the current user. No other character or byte has a special meaning
|
||||
within a path. Multiple adjacent @litchar{/} are equivalent to a
|
||||
single @litchar{/} (i.e., they act as a single path separator).
|
||||
|
||||
A path root is either @litchar{/} or a home-directory specification
|
||||
starting with @litchar{~}. A relative path whose first element starts
|
||||
with a @litchar{~} is encoded by prefixing the path with @litchar{./}.
|
||||
|
||||
Any pathname that ends with a @litchar{/} syntactically refers to a
|
||||
directory, as does any path whose last element is @litchar{.} or
|
||||
@litchar{..}, or any path that contains only a root.
|
||||
|
||||
A @|AllUnix| path is @tech{path-expand}ed by replacing a
|
||||
home-directory specification (starting with @litchar{~}) with an
|
||||
absolute path, and by replacing multiple adjacent @litchar{/}s with a
|
||||
single @litchar{/}.
|
||||
|
||||
For @scheme[(bytes->path-element _bstr)], @scheme[bstr] can start with
|
||||
a @litchar{~}, and it is encoded as a literal part of the path element
|
||||
using a @litchar{./} prefix. The @scheme[_bstr] argument must not
|
||||
contain @litchar{/}, otherwise the @exnraise[exn:fail:contract].
|
||||
|
||||
For @scheme[(path-element->bytes _path)] or
|
||||
@scheme[(path-element->string _path)], if the bytes form of
|
||||
@scheme[_path] starts with @litchar{~/.}, the @litchar{./} prefix is
|
||||
not included in the result.
|
||||
|
||||
For @scheme[(build-path _base-path _sub-path ...)], when a
|
||||
@scheme[_sub-path] starts with @litchar{./~}, the @litchar{./} is
|
||||
removed before adding the path. This conversion is performed because
|
||||
an initial sequence @litchar{./~} is the canonical way of representing
|
||||
relative paths whose first element's name starts with @litchar{~}.
|
||||
|
||||
For @scheme[(simplify-path _path _use-filesystem?)], if @scheme[_path]
|
||||
starts @litchar{./~}, the leading period is the only indicator, and
|
||||
there are no redundant @litchar{/}s, then @scheme[_path] is returned.
|
||||
|
||||
For @scheme[(split-path _path)] producing @scheme[_base],
|
||||
@scheme[_name], and @scheme[_must-be-dir?], the result @scheme[name]
|
||||
can start with @litchar{./~} if the result would otherwise start with
|
||||
@litchar{~} and it is not the start of @scheme[_path]. Furthermore, if
|
||||
@scheme[path] starts with @litchar{./~} with any non-zero number of
|
||||
@litchar{/}s between @litchar{.} and @litchar{~}, then the
|
||||
@litchar{./} is kept with the following element (i.e., they are not
|
||||
split separately).
|
||||
|
||||
Under Mac OS X, Finder aliases are zero-length files.
|
|
@ -5,66 +5,7 @@
|
|||
@define[(fileFirst s) (index (list s) (file s))]
|
||||
@define[MzAdd (italic "Scheme-specific:")]
|
||||
|
||||
@title{Platform-Specific Path Conventions}
|
||||
|
||||
@section[#:tag "mz:unixpaths"]{@|AllUnix| Paths}
|
||||
|
||||
In @|AllUnix| paths, a @litchar{/} separates elements of the path,
|
||||
@litchar{.} as a path element always means the directory indicated by
|
||||
preceding path, and @litchar{..} as a path element always means the
|
||||
parent of the directory indicated by the preceding path. A path that
|
||||
starts with a @litchar{~} indicates a user's home directory; the
|
||||
username follows the @litchar{~} (before a @litchar{/} or the end of
|
||||
the path), where @litchar{~} by itself indicates the home directory of
|
||||
the current user. No other character or byte has a special meaning
|
||||
within a path. Multiple adjacent @litchar{/} are equivalent to a
|
||||
single @litchar{/} (i.e., they act as a single path separator).
|
||||
|
||||
A path root is either @litchar{/} or a home-directory specification
|
||||
starting with @litchar{~}. A relative path whose first element starts
|
||||
with a @litchar{~} is encoded by prefixing the path with @litchar{./}.
|
||||
|
||||
Any pathname that ends with a @litchar{/} syntactically refers to a
|
||||
directory, as does any path whose last element is @litchar{.} or
|
||||
@litchar{..}, or any path that contains only a root.
|
||||
|
||||
A @|AllUnix| path is @tech{expanded} by replacing a home-directory
|
||||
specification (starting with @litchar{~}) with an absolute path, and by
|
||||
replacing multiple adjacent @litchar{/}s with a single @litchar{/}.
|
||||
|
||||
For @scheme[(bytes->path-element _bstr)], @scheme[bstr] can start with
|
||||
a @litchar{~}, and it is encoded as a literal part of the path element
|
||||
using a @litchar{./} prefix. The @scheme[_bstr] argument must not
|
||||
contain @litchar{/}, otherwise the @exnraise[exn:fail:contract].
|
||||
|
||||
For @scheme[(path-element->bytes _path)] or
|
||||
@scheme[(path-element->string _path)], if the bytes form of
|
||||
@scheme[_path] starts with @litchar{~/.}, the @litchar{./} prefix is
|
||||
not included in the result.
|
||||
|
||||
For @scheme[(build-path _base-path _sub-path ...)], when a
|
||||
@scheme[_sub-path] starts with @litchar{./~}, the @litchar{./} is
|
||||
removed before adding the path. This conversion is performed because
|
||||
an initial sequence @litchar{./~} is the canonical way of representing
|
||||
relative paths whose first element's name starts with @litchar{~}.
|
||||
|
||||
For @scheme[(simplify-path _path _use-filesystem?)], if @scheme[_path]
|
||||
starts @litchar{./~}, the leading period is the only indicator, and
|
||||
there are no redundant @litchar{/}s, then @scheme[_path] is returned.
|
||||
|
||||
For @scheme[(split-path _path)] producing @scheme[_base],
|
||||
@scheme[_name], and @scheme[_must-be-dir?], the result @scheme[name]
|
||||
can start with @litchar{./~} if the result would otherwise start with
|
||||
@litchar{~} and it is not the start of @scheme[_path]. Furthermore, if
|
||||
@scheme[path] starts with @litchar{./~} with any non-zero number of
|
||||
@litchar{/}s between @litchar{.} and @litchar{~}, then the
|
||||
@litchar{./} is kept with the following element (i.e., they are not
|
||||
split separately).
|
||||
|
||||
Under Mac OS X, Finder aliases are zero-length files.
|
||||
|
||||
@;------------------------------------------------------------------------
|
||||
@section[#:tag "mz:windowspaths"]{Windows Path Conventions}
|
||||
@title[#:tag "mz:windowspaths"]{Windows Path Conventions}
|
||||
|
||||
In general, a Windows pathname consists of an optional drive specifier
|
||||
and a drive-specific path. As noted in @secref["mz:filesystem"], a
|
||||
|
@ -101,7 +42,6 @@ parameter). Consequently, Scheme implicitly converts a path like
|
|||
|
||||
}
|
||||
|
||||
|
||||
Otherwise, Scheme follows standard Windows path conventions, but also
|
||||
adds @litchar["\\\\?\\REL"] and @litchar["\\\\?\\RED"] conventions to
|
||||
deal with paths inexpressible in the standard conventsion, plus
|
Loading…
Reference in New Issue
Block a user