summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lisplib.c22
-rw-r--r--share/txr/stdlib/with-stream.tl48
-rw-r--r--txr.1171
3 files changed, 241 insertions, 0 deletions
diff --git a/lisplib.c b/lisplib.c
index dc90a377..122256f3 100644
--- a/lisplib.c
+++ b/lisplib.c
@@ -189,6 +189,27 @@ static val struct_instantiate(val set_fun)
return nil;
}
+static val with_stream_set_entries(val dlt, val fun)
+{
+ val name[] = {
+ lit("with-out-string-stream"),
+ lit("with-out-strlist-stream"),
+ lit("with-in-string-stream"),
+ lit("with-in-string-byte-stream"),
+ lit("with-stream"),
+ nil
+ };
+ set_dlt_entries(dlt, name, fun);
+ return nil;
+}
+
+static val with_stream_instantiate(val set_fun)
+{
+ funcall1(set_fun, nil);
+ load(format(nil, lit("~a/with-stream.tl"), stdlib_path, nao));
+ return nil;
+}
+
val dlt_register(val dlt,
val (*instantiate)(val),
val (*set_entries)(val, val))
@@ -207,6 +228,7 @@ void lisplib_init(void)
dlt_register(dl_table, with_resources_instantiate, with_resources_set_entries);
dlt_register(dl_table, path_test_instantiate, path_test_set_entries);
dlt_register(dl_table, struct_instantiate, struct_set_entries);
+ dlt_register(dl_table, with_stream_instantiate, with_stream_set_entries);
}
val lisplib_try_load(val sym)
diff --git a/share/txr/stdlib/with-stream.tl b/share/txr/stdlib/with-stream.tl
new file mode 100644
index 00000000..ac7e826a
--- /dev/null
+++ b/share/txr/stdlib/with-stream.tl
@@ -0,0 +1,48 @@
+;; Copyright 2015
+;; Kaz Kylheku <kaz@kylheku.com>
+;; Vancouver, Canada
+;; All rights reserved.
+;;
+;; Redistribution of this software in source and binary forms, with or without
+;; modification, is permitted provided that the following two conditions are met.
+;;
+;; Use of this software in any manner constitutes agreement with the disclaimer
+;; which follows the two conditions.
+;;
+;; 1. Redistributions of source code must retain the above copyright
+;; notice, this list of conditions and the following disclaimer.
+;; 2. Redistributions in binary form must reproduce the above copyright
+;; notice, this list of conditions and the following disclaimer in
+;; the documentation and/or other materials provided with the
+;; distribution.
+;;
+;; THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+;; WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+;; MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE
+;; COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DAMAGES, HOWEVER CAUSED,
+;; AND UNDER ANY THEORY OF LIABILITY, ARISING IN ANY WAY OUT OF THE USE OF THIS
+;; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+(defmacro with-out-string-stream ((stream) . body)
+ ^(let ((,stream (make-string-output-stream)))
+ ,*body
+ (get-string-from-stream ,stream)))
+
+(defmacro with-out-strlist-stream ((stream) . body)
+ ^(let ((,stream (make-strlist-output-stream)))
+ ,*body
+ (get-list-from-stream ,stream)))
+
+(defmacro with-in-string-stream ((stream string) . body)
+ ^(let ((,stream (make-string-input-stream ,string)))
+ ,*body))
+
+(defmacro with-in-string-byte-stream ((stream string) . body)
+ ^(let ((,stream (make-string-byte-input-stream ,string)))
+ ,*body))
+
+(defmacro with-stream ((var stream) . body)
+ ^(let ((,var ,stream))
+ (unwind-protect
+ (progn ,*body)
+ (close-stream ,var))))
diff --git a/txr.1 b/txr.1
index 80cdd52c..4cffd067 100644
--- a/txr.1
+++ b/txr.1
@@ -29744,6 +29744,135 @@ a string output stream given by
The string output stream is
finalized, so that further output is no longer possible.
+.coNP Macro @ with-in-string-stream
+.synb
+.mets (with-in-string-stream >> ( stream-var << string )
+.mets \ \ << body-form *)
+.syne
+.desc
+The
+.code with-in-string-stream
+macro binds the symbol
+.meta stream-var
+as a variable, initializing it with a newly created
+string input stream. The string input stream is
+constructed from
+.meta string
+as if by the
+.cblk
+.meti (make-string-input-stream << string )
+.cble
+expression.
+
+Then it evaluates the
+.metn body-form -s
+in the scope of the variable.
+
+The value of the last
+.meta body-form
+is returned, or else
+.code nil
+if no forms are present.
+
+The
+.meta stream-var
+argument must be a bindable symbol,
+as defined by the
+.code bindable
+function.
+
+The
+.meta string
+argument must be a form
+which evaluates to a character string value.
+
+.coNP Macro @ with-in-string-byte-stream
+.synb
+.mets (with-in-string-byte-stream >> ( stream-var << string )
+.mets \ \ << body-form *)
+.syne
+.desc
+The
+.code with-in-string-byte-stream
+macro binds the symbol
+.meta stream-var
+as a variable, initializing it with a newly created
+string byte input stream. The string input stream is
+constructed from
+.meta string
+as if by the
+.cblk
+.meti (make-string-byte-input-stream << string )
+.cble
+expression.
+
+Then it evaluates the
+.metn body-form -s
+in the scope of the variable.
+
+The value of the last
+.meta body-form
+is returned, or else
+.code nil
+if no forms are present.
+
+The
+.meta string
+argument must be a form
+which evaluates to a character string value.
+
+.coNP Macro @ with-out-string-stream
+.synb
+.mets (with-out-string-stream <> ( stream-var ) << body-form *)
+.syne
+.desc
+The
+.code with-out-string-stream
+macro binds the symbol specified
+by the
+.meta stream-var
+argument as a variable, initializing it
+with a newly created string output stream. The output
+stream is created as if by the
+.code make-string-output-stream
+function.
+
+Then it evaluates
+.metn body-form -s
+in the scope of that variable.
+
+After these forms are evaluated, the string is extracted
+from the string output stream, as if by the
+.code get-string-from-stream
+function, and returned as the result value
+of the form.
+
+.coNP Macro @ with-out-strlist-stream
+.synb
+.mets (with-out-strlist-stream <> ( stream-var ) << body-form *)
+.syne
+.desc
+The
+.code with-out-strlist-stream
+macro binds the symbol specified
+by the
+.meta stream-var
+argument as a variable, initializing it
+with a newly created string list output stream. The output
+stream is created as if by the
+.code make-strlist-output-stream
+function.
+
+Then it evaluates
+.metn body-form -s
+in the scope of that variable.
+
+After these forms are evaluated, the string list is extracted
+from the string output stream, as if by the
+.code get-strlist-from-stream
+function, and returned as the result value
+of the form.
+
.coNP Function @ close-stream
.synb
.mets (close-stream < stream <> [ throw-on-error-p ])
@@ -29783,6 +29912,48 @@ function throws an exception if an error occurs during the close operation
instead of returning
.codn nil .
+.coNP Macro @ with-stream
+.synb
+.mets (with-stream >> ( stream-var << init-form )
+.mets \ \ << body-form *)
+.syne
+.desc
+The
+.code with-stream
+binds the variable whose name is given by the
+.meta stream-var
+argument, and macro arranges for the evaluation of
+.metn body-form -s
+in the scope of that variable.
+
+The variable is initialized with the value produced
+by the evaluation of
+.meta init-form
+which must be an expression which evaluates to a stream.
+
+After each
+.meta body-form
+is evaluated, the stream is closed, as if by the
+.cblk
+.meti (close-stream << stream-var )
+.cble
+expression.
+
+The value of the last
+.meta body-form
+then becomes the result value of the form,
+or else
+.code nil
+if these forms are absent.
+
+If the evaluation of the
+.metn body-form -s
+is abandoned, the stream is still closed. That is to say,
+the closure of the stream is a protected action, as if by
+the
+.code unwind-protect
+operator.
+
.coNP Functions @, get-error @ get-error-str and @ clear-error
.synb
.mets (get-error << stream )