From 1ef8071c738db67214e7d20502496146d2a40821 Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Fri, 18 Mar 2016 06:29:25 -0700 Subject: New l and u letters in stream open mode strings. * stream.c (parse_mode): Recognize "l" and "u", and set new flags. (set_mode_props): More complicated behavior to integrate the new options with the line mode defaulting behavior of "i". * stream.h (struct stdio_mode): New members unbuf and linebuf. All members become bit fields of width 1. (stdio_mode_init_trivial): Initializers for new members. * txr.1: Documented. --- stream.c | 28 ++++++++++++++++++++++++---- stream.h | 18 ++++++++++-------- txr.1 | 33 ++++++++++++++++++++++++++++++--- 3 files changed, 64 insertions(+), 15 deletions(-) diff --git a/stream.c b/stream.c index e9ba359b..5798efcb 100644 --- a/stream.c +++ b/stream.c @@ -1186,6 +1186,20 @@ static struct stdio_mode parse_mode(val mode_str) case 'i': m.interactive = 1; break; + case 'l': + if (m.unbuf) { + m.malformed = 1; + return m; + } + m.linebuf = 1; + break; + case 'u': + if (m.linebuf) { + m.malformed = 1; + return m; + } + m.unbuf = 1; + break; default: m.malformed = 1; return m; @@ -1245,12 +1259,18 @@ val normalize_mode(struct stdio_mode *m, val mode_str) val set_mode_props(const struct stdio_mode m, val stream) { - if (m.interactive) { + if (m.interactive || m.linebuf || m.unbuf) { struct stdio_handle *h = coerce(struct stdio_handle *, cobj_handle(stream, stdio_stream_s)); - if (h->f && m.write) - setvbuf(h->f, (char *) NULL, _IOLBF, 0); - stream_set_prop(stream, real_time_k, t); + if (h->f) { + if (m.write && (m.linebuf || (m.interactive && !m.unbuf))) + setvbuf(h->f, 0, _IOLBF, 0); + else if (m.unbuf) + setbuf(h->f, 0); + } + + if (m.interactive) + stream_set_prop(stream, real_time_k, t); } return stream; } diff --git a/stream.h b/stream.h index b96a0ae6..2474ce13 100644 --- a/stream.h +++ b/stream.h @@ -83,16 +83,18 @@ struct strm_ops { } struct stdio_mode { - int malformed; - int read; - int write; - int create; - int append; - int binary; - int interactive; + unsigned malformed : 1; + unsigned read : 1; + unsigned write : 1; + unsigned create : 1; + unsigned append : 1; + unsigned binary : 1; + unsigned interactive : 1; + unsigned unbuf : 1; + unsigned linebuf : 1; }; -#define stdio_mode_init_trivial(read) { 0, read, 0, 0, 0, 0, 0 } +#define stdio_mode_init_trivial(read) { 0, read, 0, 0, 0, 0, 0, 0, 0 } #define std_input (deref(lookup_var_l(nil, stdin_s))) #define std_output (deref(lookup_var_l(nil, stdout_s))) diff --git a/txr.1 b/txr.1 index a86c4ca1..8dcc2c6b 100644 --- a/txr.1 +++ b/txr.1 @@ -34430,17 +34430,44 @@ argument is omitted, mode .str r is used. +Additional option letters are supported in +.meta mode-string +which are not feature of the standard C +.code fopen +function. These letters cannot occur anywhere in the string. They can occur in the +same position as the +.str b +option, in any order with respect to that +.str b +or each other. Their relative order doesn't matter. + +The letter +.str l +indicates that the stream will be line buffered. This means that an implicit +flush operation takes place whenever the newline character is output. + +The letter +.str u +indicates that the stream will be unbuffered. + +It is erroneous for both +.str l +and +.str u +to be specified. + The option letter .str i -is supported. If present, it will create a stream which has the real-time +indicates that the stream will have the real-time property set. For a description of the semantics, see the .code real-time-stream-p function. Briefly, this property affects the semantics of lazy lists which draw input from the stream. In addition, for a stream opened for writing or reading and writing, the .str i -mode letter specifies that the stream will be line-buffered. This means that an -implicit flush operation takes place whenever the newline character is output. +mode letter specifies that the stream will be line buffered, unless +specified as unbuffered with +.strn u . .coNP Function @ open-tail .synb -- cgit v1.2.3