From c0999f05eede65e0755dc05013d32d10a82e5ccd Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Mon, 2 Jul 2007 03:43:47 +0000 Subject: [PATCH] doc work on io reference svn: r6792 --- collects/scribble/latex-render.ss | 2 + .../scribblings/reference/file-ports.scrbl | 199 ++++++++++++++++++ collects/scribblings/reference/mz.ss | 3 + collects/scribblings/reference/pipes.scrbl | 39 ++++ .../scribblings/reference/port-buffers.scrbl | 112 ++++++++++ .../scribblings/reference/port-procs.scrbl | 51 +++++ collects/scribblings/reference/ports.scrbl | 42 +--- 7 files changed, 412 insertions(+), 36 deletions(-) create mode 100644 collects/scribblings/reference/file-ports.scrbl create mode 100644 collects/scribblings/reference/pipes.scrbl create mode 100644 collects/scribblings/reference/port-buffers.scrbl create mode 100644 collects/scribblings/reference/port-procs.scrbl diff --git a/collects/scribble/latex-render.ss b/collects/scribble/latex-render.ss index a666be2a4e..6784aad28d 100644 --- a/collects/scribble/latex-render.ss +++ b/collects/scribble/latex-render.ss @@ -28,10 +28,12 @@ (printf "\\parskip=10pt%\n") (printf "\\parindent=0pt%\n") (printf "\\usepackage{graphicx}\n") + (printf "\\usepackage{hyperref}\n") (printf "\\renewcommand{\\rmdefault}{ptm}\n") ;; (printf "\\usepackage{fullpage}\n") (printf "\\usepackage{longtable}\n") (printf "\\usepackage[usenames,dvipsnames]{color}\n") + (printf "\\hypersetup{bookmarks=true,bookmarksopen=true,bookmarksnumbered=true}\n") (define-color "schemeplain" "black") (printf "\\newcommand{\\schemekeyword}[1]{{\\color{black}{\\texttt{\\textbf{#1}}}}}\n") (printf "\\newcommand{\\schemesyntaxlink}[1]{\\schemekeyword{#1}}\n") diff --git a/collects/scribblings/reference/file-ports.scrbl b/collects/scribblings/reference/file-ports.scrbl new file mode 100644 index 0000000000..461fafea2b --- /dev/null +++ b/collects/scribblings/reference/file-ports.scrbl @@ -0,0 +1,199 @@ +#reader(lib "docreader.ss" "scribble") +@require["mz.ss"] + +@title{File Ports} + +A port created by @scheme[open-input-file], @scheme[open-output-file], +@scheme[subprocess], and related functions is a @defterm{file-stream +port}. The initial input, output, and error ports in stand-alone +MzScheme are also file-stream ports. The @scheme[file-stream-port?] +predicate recognizes file-stream ports. + +When an input or output file-stream port is created, it is placed into +the management of the current custodian (see +@secref["mz:custodians"]). + +@defproc[(open-input-file [path path-string?] + [#:mode mode-flag (one-of/c 'binary 'text) 'binary]) + input-port?]{ + +Opens the file specified by @scheme[path] for input. The +@scheme[mode-flag] argument specifies how the file's bytes are +translated on input: + +@itemize{ + + @item{@scheme['binary] --- bytes are returned from the port + exactly as they are read from the file.} + + @item{@scheme['text] --- return and linefeed bytes (10 and 13) + as read from the file are filtered by the port in a + platform specific manner: + + @itemize{ + + @item{@|AllUnix|: no filtering occurs.} + + @item{Windows: a return-linefeed combination from a file is returned + by the port as a single linefeed; no filtering occurs for + return bytes that are not followed by a linefeed, or for a + linefeed that is not preceded by a return.} + }} +} + +Under Windows, @scheme['text] mode works only with regular files; +attempting to use @scheme['text] with other kinds of files triggers an +@scheme[exn:fail:filesystem] exception. + +Otherwise, the file specified by @scheme[path] need not be a regular +file. It might a device that is connected through the filesystem, such +as @file{aux} under Windows or @file{/dev/null} under Unix. In all +cases, the port is buffered by default. + +The port produced by @scheme[open-input-port] should be explicitly +closed, either though @scheme[close-input-port] or indirectly via +@scheme[custodian-shutdown-all], to release the OS-level file +handle. The input port will not closed automatically if it is +otherwise available for garbage collection (see +@secref["mz:gc-model"]); a @tech{will} could be associated input port +to close it more automatically (see @secref["mz:wills"]). } + +@defproc[(open-output-file [path path-string?] + [#:mode mode-flag (one-of/c 'binary 'text) 'binary] + [#:exists exists-flag (one-of/c 'error 'append 'update + 'replace 'truncate 'truncate/replace) 'error]) + output-port?]{ + +Opens the file specified by @scheme[path] for output. The +@scheme[mode-flag] argument specifies how bytes written to the port +are translated when written to the file: + +@itemize{ + + @item{@scheme['binary] --- bytes are written to the file exactly + as written to the port.} + + @item{@scheme['text] --- under Windows, a linefeed byte (10) written + to the port is translated to a return-linefeed combination in the + file; no filtering occurs for returns.} + +} + +Under Windows, @scheme['text] mode works only with regular files; +attempting to use @scheme['text] with other kinds of files triggers an +@scheme[exn:fail:filesystem] exception. + +The @scheme[exists-flag] argument specifies how to handle the case +that the file already exists. + +@itemize{ + + @item{@scheme['error] --- raise @scheme[exn:fail:filesystem].} + + @item{@scheme['replace] --- remove the old file and write a new one.} + + @item{@scheme['truncate] --- removed all old data.} + + @item{@scheme['truncate/replace] --- try @scheme['truncate]; if it + fails (perhaps due to file permissions), try @scheme['replace].} + + @item{@scheme['update] --- open an existing file without truncating it; + if the file does not exist, the @exnraise[exn:fail:filesystem].} + + @item{@scheme['append] --- append to the end of the file under + @|AllUnix|; under Windows, @scheme['append] is equivalent to + @scheme['update], except that the file position is immediately set + to the end of the file after opening it.} + +} + +The file specified by @scheme[path] need not be a regular file. It +might a device that is connected through the filesystem, such as +@file{aux} under Windows or @file{/dev/null} under Unix. The output +port is block-buffered by default, unless the file corresponds to a +terminal, in which case is it line buffered bu default. + +The port produced by @scheme[open-output-port] should be explicitly +closed, either though @scheme[close-output-port] or indirectly via +@scheme[custodian-shutdown-all], to release the OS-level file +handle. The output port will not closed automatically if it is +otherwise available for garbage collection (see +@secref["mz:gc-model"]); a @tech{will} could be associated input port +to close it more automatically (see @secref["mz:wills"]).} + +@defproc[(open-input-output-file [path path-string?] + [#:mode mode-flag (one-of/c 'binary 'text) 'binary] + [#:exists exists-flag (one-of/c 'error 'append 'update + 'replace 'truncate 'truncate/replace) 'error]) + (values input-port? output-port?)]{ + +Like @scheme[open-output-file], but producing two values: an input +port and an output port. The two ports are connected in that they +share the underlying file device. This procedure is intended for use +with special devices that can be opened by only one process, such as +@file{COM1} in Windows. For regular files, sharing the device can be +confusing. For example, using one port does not automatically flush +the other port's buffer, and reading or writing in one port moves the +file position (if any) for the other port. For regular files, use +separate @scheme[open-input-file] and @scheme[open-output-file] calls +to avoid confusion.} + +@defproc[(call-with-input-file [path path-string?] + [proc (input-port? . -> . any)] + [#:mode mode-flag (one-of/c 'binary 'text) 'binary]) + any]{ +Calls @scheme[open-input-port] with the @scheme[path] and +@scheme[mode-flag] arguments, and passes the resulting port +to @scheme[proc]. The result of @scheme[proc] is the result of the +@scheme[call-with-input-file] call, but the newly opened port is closed +when @scheme[thunk] return.} + +@defproc[(call-with-output-file [path path-string?] + [proc (output-port? . -> . any)] + [#:mode mode-flag (one-of/c 'binary 'text) 'binary] + [#:exists exists-flag (one-of/c 'error 'append 'update + 'replace 'truncate 'truncate/replace) 'error]) + any]{ +Analogous to @scheme[call-with-input-file], but passing @scheme[path], +@scheme[mode-flag] and @scheme[exists-flag] to +@scheme[open-output-file].} + +@defproc[(call-with-input-file* [path path-string?] + [proc (input-port? . -> . any)] + [#:mode mode-flag (one-of/c 'binary 'text) 'binary]) + any]{ +Like @scheme[call-with-input-file], but the newly opened port is +closed whenever control escapes the the dynamic extent of the +@scheme[call-with-input-file*] call, whether through @scheme[proc]'s +return, a continuation application, or a prompt-based abort.} + +@defproc[(call-with-output-file* [path path-string?] + [proc (output-port? . -> . any)] + [#:mode mode-flag (one-of/c 'binary 'text) 'binary] + [#:exists exists-flag (one-of/c 'error 'append 'update + 'replace 'truncate 'truncate/replace) 'error]) + any]{ +Like @scheme[call-with-output-file], but the newly opened port is +closed whenever control escapes the the dynamic extent of the +@scheme[call-with-output-file*] call, whether through @scheme[proc]'s +return, a continuation application, or a prompt-based abort.} + +@defproc[(with-input-from-file [path path-string?] + [thunk (-> any)] + [#:mode mode-flag (one-of/c 'binary 'text) 'binary]) + any]{ +Like @scheme[call-with-input-file*], but instead of passing the newly +opened port to the given procedure argument, the port is installed as +the current input port (see @scheme[current-input-port]) using +@scheme[parameterize] around the call to @scheme[thunk].} + +@defproc[(with-output-to-file [path path-string?] + [thunk (-> any)] + [#:mode mode-flag (one-of/c 'binary 'text) 'binary] + [#:exists exists-flag (one-of/c 'error 'append 'update + 'replace 'truncate 'truncate/replace) 'error]) + any]{ +Like @scheme[call-with-output-file*], but instead of passing the newly +opened port to the given procedure argument, the port is installed as +the current output port (see @scheme[current-output-port]) using +@scheme[parameterize] around the call to @scheme[thunk].} diff --git a/collects/scribblings/reference/mz.ss b/collects/scribblings/reference/mz.ss index 0cac5b43b0..e05eec222d 100644 --- a/collects/scribblings/reference/mz.ss +++ b/collects/scribblings/reference/mz.ss @@ -9,6 +9,9 @@ (provide (all-from (lib "manual.ss" "scribble")) (all-from (lib "eval.ss" "scribble"))) + (define AllUnix "Unix and Mac OS X") + (provide AllUnix) + (define (*exnraise s) (make-element #f (list s " exception is raised"))) (define-syntax exnraise diff --git a/collects/scribblings/reference/pipes.scrbl b/collects/scribblings/reference/pipes.scrbl new file mode 100644 index 0000000000..3532457642 --- /dev/null +++ b/collects/scribblings/reference/pipes.scrbl @@ -0,0 +1,39 @@ +#reader(lib "docreader.ss" "scribble") +@require["mz.ss"] + +@title[#:tag "mz:pipeports"]{Pipes} + +A Scheme @deftech{pipe} is internal to Scheme, and not related to +OS-level pipes (which are @tech{file-stream ports}) for communicating +between different processes. + +@defproc[(make-pipe [limit positive-exact-integer? #f] + [input-name-v any/c #f] + [output-name-v any/c #f]) + any]{ + +Returns two port values: the first port is an input port and the +second is an output port. Data written to the output port is read from +the input port, with no intermediate buffering. The ports do not need +to be explicitly closed. + +If @scheme[limit] is @scheme[#f], the new pipe holds an unlimited +number of unread bytes (i.e., limited only by the available +memory). If @scheme[limit] is a positive number, then the pipe will +hold at most @scheme[limit] unread/unpeeked bytes; writing to the +pipe's output port thereafter will block until a read or peek from the +input port makes more space available. (Peeks effectively extend the +port's capacity until the peeked bytes are read.) + +The optional @scheme[input-name-v] and @scheme[output-name-v] are used +as the names for the returned input and out ports, respectively, if +they are supplied. (See also @scheme[object-name].) Otherwise, the +name of each port is @scheme['pipe].} + +@defproc[(pipe-content-length [pipe-port port?]) any]{ + +Returns the number of bytes contained in a pipe, where +@scheme[pipe-port] is either of the pipe's ports produced by +@scheme[make-pipe]. The pipe's content length counts all bytes that +have been written to the pipe and not yet read (though possibly +peeked).} diff --git a/collects/scribblings/reference/port-buffers.scrbl b/collects/scribblings/reference/port-buffers.scrbl new file mode 100644 index 0000000000..af8f9aaa82 --- /dev/null +++ b/collects/scribblings/reference/port-buffers.scrbl @@ -0,0 +1,112 @@ +#reader(lib "docreader.ss" "scribble") +@require["mz.ss"] + +@title[#:tag "mz:port-buffers"]{Port Buffers and Positions} + +Some ports---especially those that read from and write to files---are +internally buffered: + +@itemize{ + + @item{An input port is typically block buffered by default, which + means that on any read, the buffer is filled with + immediately-available bytes to speed up future reads. Thus, if + a file is modified between a pair of reads to the file, the + second read can produce stale data. Calling + @scheme[file-position] to set an input port's file position + flushes its buffer.} + + @item{And output port is typically block buffered by default, though + a terminal output port is line buffered, and the initial error + output port is unbuffered. An output buffer is filled with a + sequence of written bytes to be committed as a group, either + when the buffer is full (in block mode), when a newline is + written (in line mode), when the port is closed via + @scheme[close-output-port], or when a flush is explicitly + requested via a procedure like @scheme[flush-output].} + +} + +If a port supports buffering, its buffer mode can be changed via +@scheme[file-stream-buffer-mode] (even if the port is not a +@tech{file-stream port}). + +For an input port, peeking always places peeked bytes into the port's +buffer, even when the port's buffer mode is @scheme['none]; +furthermore, on some platforms, testing the port for input (via +@scheme[char-ready?] or @scheme[sync]) may be implemented with a +peek. If an input port's buffer mode is @scheme['none], then at most +one byte is read for @scheme[read-bytes-avail!*], +@scheme[read-bytes-avail!], @scheme[peek-bytes-avail!*], or +@scheme[peek-bytes-avail!]; if any bytes are buffered in the port +(e.g., to satisfy a previous peek), the procedures may access multiple +buffered bytes, but no further bytes are read. + +In addition, the initial current output and error ports are +automatically flushed when @scheme[read], @scheme[read-line], +@scheme[read-bytes], @scheme[read-string], etc. are performed on the +initial standard input port; more precisely, flushing is performed by +the default port read handler (see @secref["mz:portreadhandler"]). + +@defproc[(flush-output [out output-port? (current-output-port)]) void?]{ + +@index['("ports" "flushing")]{Forces} all buffered data in the given +output port to be physically written. Only @tech{file-stream ports}, +TCP ports, and custom ports (see @secref["mz:customport"]) use +buffers; when called on a port without a buffer, @scheme[flush-output] +has no effect.} + +@defproc*[([(file-stream-buffer-mode [port port?]) (one-of/c 'none 'line 'block #f)] + [(file-stream-buffer-mode [port port?][mode (one-of/c 'none 'line 'block)]) void?])]{ + +Gets or sets the buffer mode for @scheme[port], if +possible. @tech{File-stream ports} support setting the buffer mode, +TCP ports (see @secref["mz:networking"]) support setting and getting +the buffer mode, and custom ports (see @secref["mz:customport"]) may +support getting and setting buffer modes. + +If @scheme[mode] is provided, it must be one of @scheme['none], +@scheme['line] (output only), or @scheme['block], and the port's +buffering is set accordingly. If the port does not support setting the +mode, the @exnraise[exn:fail]. + +If @scheme[mode] is not provided, the current mode is returned, or +@scheme[#f] is returned if the mode cannot be determined. If +@scheme[file-stream-port] is an input port and @scheme[mode] is +@scheme['line], the @exnraise[exn:fail:contract].} + +@defproc*[([(file-position [port port?]) nonnegative-exact-integer?] + [(file-position [port port?] [pos (or/c nonnegative-exact-integer? eof-object?)]) void?])]{ + +Returns or sets the current read/write position of @scheme[port]. + +Calling @scheme[file-position] without a position on a +non-file/non-string input port returns the number of bytes that have +been read from that port if the position is known (see +@secref["mz:linecol"]), otherwise the @exnraise[exn:fail:filesystem]. + +For @tech{file-stream ports} and string ports, the position-setting +variants sets the read/write position to @scheme[pos] relative to the +beginning of the file/string if @scheme[pos] is a number, or to the +current end of the file/string if @scheme[pos] is @scheme[eof]. In +position-setting mode, @scheme[file-position] raises the +@scheme[exn:fail:contract] exception for port kinds other than +file-stream and string ports. Furthermore, not all @tech{file-stream +ports} support setting the position; f @scheme[file-position] is +called with a position argument on such a @tech{file-stream port}, the +@exnraise[exn:fail:filesystem]. + +When @scheme[file-position] sets the position @scheme[pos] beyond the +current size of an output file or string, the file/string is enlarged +to size @scheme[pos] and the new region is filled with @scheme[0] +bytes. If @scheme[pos] is beyond the end of an input file or string, +then reading thereafter returns @scheme[eof] without changing the +port's position. + +When changing the file position for an output port, the port is first +flushed if its buffer is not empty. Similarly, setting the position +for an input port clears the port's buffer (even if the new position +is the same as the old position). However, although input and output +ports produced by @scheme[open-input-output-file] share the file +position, setting the position via one port does not flush the other +port's buffer.} diff --git a/collects/scribblings/reference/port-procs.scrbl b/collects/scribblings/reference/port-procs.scrbl new file mode 100644 index 0000000000..00b49e1ecf --- /dev/null +++ b/collects/scribblings/reference/port-procs.scrbl @@ -0,0 +1,51 @@ +#reader(lib "docreader.ss" "scribble") +@require["mz.ss"] + +@title[#:tag "mz:port-ops"]{Managing Ports} + +@defproc[(input-port? [v any/c]) boolean?]{ +Returns @scheme[#t] if @scheme[v] is an input port, @scheme[#f] otherwise.} + +@defproc[(output-port? [v any/c]) boolean?]{ +Returns @scheme[#t] if @scheme[v] is an output port, @scheme[#f] otherwise.} + +@defproc[(port? [v any/c]) boolean?]{ +Returns @scheme[#t] if either @scheme[(input-port? v)] or +@scheme[(output-port? v)] is @scheme[#t], @scheme[#f] otherwise.} + +@defproc[(close-input-port [in input-port?]) void?]{ +Closes the input port @scheme[in]. For some kinds of ports, closing +the port releases lower-level resources, such as a file handle. If +the port is already closed, @scheme[close-input-port] has no effect.} + +@defproc[(close-output-port [out output-port?]) void?]{ +Closes the output port @scheme[out]. For some kinds of ports, closing +the port releases lower-level resources, such as a file handle. Also, +if the port is buffered, closing may first flush the port before +closing it, and this flushing process can block. If the port is +already closed, @scheme[close-output-port] has no effect.} + +@defproc[(port-closed? [port port?]) boolean?]{ +Returns @scheme[#t] if the input or output port @scheme[port] is +closed, @scheme[#f] otherwise.} + +@defparam[current-input-port in input-port?]{A parameter that +determines a default input port for many operations, such as +@scheme[read].} + +@defparam[current-output-port out output-port?]{A parameter that +determines a default output port for many operations, such as +@scheme[write].} + +@defparam[current-error-port out output-port?]{A parameter that +determines an output port that is typically used for errors and +logging. For example, the default error display handler writes to this +port.} + +@defproc[(file-stream-port? [port port?]) boolean?]{ +Returns @scheme[#t] if the given port is a file-stream port (see +@secref["mz:file-ports"]), @scheme[#f] otherwise.} + +@defproc[(terminal-port? [port port?]) boolean?]{ +Returns @scheme[#t] if the given port is attached to an interactive +terminal, @scheme[#f] otherwise.} diff --git a/collects/scribblings/reference/ports.scrbl b/collects/scribblings/reference/ports.scrbl index 1095c7eaaa..f7bb38bda2 100644 --- a/collects/scribblings/reference/ports.scrbl +++ b/collects/scribblings/reference/ports.scrbl @@ -1,7 +1,7 @@ #reader(lib "docreader.ss" "scribble") @require["mz.ss"] -@title[#:tag "mz:ports"]{Ports} +@title[#:tag "mz:ports" #:style 'toc]{Ports} @deftech{Ports} produce and consume bytes. When a port is provided to a character-based operation, such as @scheme[read], the port's bytes @@ -42,40 +42,10 @@ Unix terminal returns an end-of-file when the user types control-D; if the user provides more input, the port returns additional bytes after the end-of-file. -@defproc[(input-port? [v any/c]) boolean?]{ -Returns @scheme[#t] if @scheme[v] is an input port, @scheme[#f] otherwise.} - -@defproc[(output-port? [v any/c]) boolean?]{ -Returns @scheme[#t] if @scheme[v] is an output port, @scheme[#f] otherwise.} - -@defproc[(port? [v any/c]) boolean?]{ -Returns @scheme[#t] if either @scheme[(input-port? v)] or -@scheme[(output-port? v)] is @scheme[#t], @scheme[#f] otherwise.} - -@defproc[(close-input-port [in input-port?]) void?]{ -Closes the input port @scheme[in]. For some kinds of ports, closing -the port releases lower-level resources, such as a file handle. If -the port is already closed, @scheme[close-input-port] has no effect.} - -@defproc[(close-output-port [out output-port?]) void?]{ -Closes the output port @scheme[out]. For some kinds of ports, closing -the port releases lower-level resources, such as a file handle. Also, -if the port is buffered, closing may first flush the port before -closing it, and this flushing process can block. If the port is -already closed, @scheme[close-output-port] has no effect.} - -@defproc[(port-closed? [port port?]) boolean?]{ -Returns @scheme[#t] if the input or output port @scheme[port] is -closed, @scheme[#f] otherwise.} - -@defparam[current-output-port output-port]{A parameter.} - -@defproc[(file-stream-port? [port port?]) boolean?]{ -Returns @scheme[#t] if the given port is a file-stream port (see -@secref["mz:file-ports"], @scheme[#f] otherwise.} - -@defproc[(terminal-port? [port port?]) boolean?]{ -Returns @scheme[#t] if the given port is attached to an interactive -terminal, @scheme[#f] otherwise.} +@;------------------------------------------------------------------------ +@local-table-of-contents[] +@include-section["port-procs.scrbl"] +@include-section["file-ports.scrbl"] +@include-section["pipes.scrbl"]