summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2016-03-18 06:29:25 -0700
committerKaz Kylheku <kaz@kylheku.com>2016-03-18 06:29:25 -0700
commit1ef8071c738db67214e7d20502496146d2a40821 (patch)
tree6b552ee894deab4c77915e45a8c96082ab42f850
parente84da36197b809c50a0c43cceb5c7b27b3d5733e (diff)
downloadtxr-1ef8071c738db67214e7d20502496146d2a40821.tar.gz
txr-1ef8071c738db67214e7d20502496146d2a40821.tar.bz2
txr-1ef8071c738db67214e7d20502496146d2a40821.zip
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.
-rw-r--r--stream.c28
-rw-r--r--stream.h18
-rw-r--r--txr.133
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