diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2016-03-14 22:00:51 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2016-03-14 22:00:51 -0700 |
commit | 56da0c3895ae502a6e17064a8e3ad588694ae910 (patch) | |
tree | 590143197eb2c2d1f73cf700389047cec2bd358a | |
parent | 60ac365c8dbfce9f481fbfe58d4baae70df889b4 (diff) | |
download | txr-56da0c3895ae502a6e17064a8e3ad588694ae910.tar.gz txr-56da0c3895ae502a6e17064a8e3ad588694ae910.tar.bz2 txr-56da0c3895ae502a6e17064a8e3ad588694ae910.zip |
@(output)_destination can be a stream.
* match.c (complex_open): If name is a stream object, just
return it.
(v_output): Do not close the output stream if it came
from a destination expression specifying an existing
stream, and thus wasn't created inside complex_open.
* txr.1: Document stream destination in output directive.
-rw-r--r-- | match.c | 46 | ||||
-rw-r--r-- | txr.1 | 18 |
2 files changed, 37 insertions, 27 deletions
@@ -1538,33 +1538,37 @@ static val txeval_allow_ub(val spec, val form, val bindings) static val complex_open(val name, val output, val append, val nothrow) { - val fc = car(name); - val result = nil; + if (streamp(name)) { + return name; + } else { + val fc = car(name); + val result = nil; - if (fc == chr('$') && output) - uw_throwf(query_error_s, lit("cannot output to directory: ~a"), - name, nao); + if (fc == chr('$') && output) + uw_throwf(query_error_s, lit("cannot output to directory: ~a"), + name, nao); - uw_catch_begin (if2(nothrow, cons(error_s, nil)), exc_sym, exc); + uw_catch_begin (if2(nothrow, cons(error_s, nil)), exc_sym, exc); - if (fc == chr('-')) { - result = output ? std_output : std_input; - } else if (fc == chr('!')) { - result = open_command(cdr(name), output ? lit("w") : lit("r")); - } else if (fc == chr('$')) { - result = open_directory(cdr(name)); - } else { - result = open_file(name, - output ? append ? lit("a") : lit("w") : lit("r")); - } + if (fc == chr('-')) { + result = output ? std_output : std_input; + } else if (fc == chr('!')) { + result = open_command(cdr(name), output ? lit("w") : lit("r")); + } else if (fc == chr('$')) { + result = open_directory(cdr(name)); + } else { + result = open_file(name, + output ? append ? lit("a") : lit("w") : lit("r")); + } - uw_catch (exc_sym, exc) { (void) exc; } + uw_catch (exc_sym, exc) { (void) exc; } - uw_unwind { } + uw_unwind { } - uw_catch_end; + uw_catch_end; - return result; + return result; + } } static val robust_length(val obj) @@ -3245,7 +3249,7 @@ static val v_output(match_files_ctx *c) if (named_var) c->bindings = acons(named_var, stream, c->bindings); - else + else if (!streamp(dest)) close_stream(stream, t); } @@ -7231,18 +7231,24 @@ directive is: @(end) .cble -The optional -.meta destination -is a string which gives the path name of +If the directive has arguments, then the first one is evaluated. +If it is an object other than a keyword symbol, then it specifies +the optional +.metn destination . +Any remaining arguments after the optional destination are +the keyword list. If the destination is missing, then the +entire argument list is a keyword list. + +The destination may be a string which gives the path name of a file to open for output. If the name is .code - it instead denotes standard output, and if it begins with .code ! then the rest of the shell is treated as a shell command -to which the output is piped. +to which the output is piped. The destination string may be specified as a +variable which holds text, as a string literal or as a quasiliteral -The destination may be specified as a variable -which holds text, as a string literal or as a quasiliteral +Alternatively, the destination may be a stream object. The keyword list consists of a mixture of boolean keywords which do not have an argument, or keywords with arguments. |