diff options
-rw-r--r-- | ChangeLog | 51 | ||||
-rw-r--r-- | stream.c | 281 | ||||
-rw-r--r-- | stream.h | 11 | ||||
-rw-r--r-- | syslog.c | 53 |
4 files changed, 272 insertions, 124 deletions
@@ -1,5 +1,56 @@ 2015-07-29 Kaz Kylheku <kaz@kylheku.com> + Deriving streams from the same base, so + we can give streams some common slots. + + * stream.c (strm_base_init, strm_base_cleanup, strm_base_mark, + stream_destroy_op, stream_mark_op): New functions. + (null_ops): Switch to stream_destroy_op and stream_mark_op. + (make_null_stream): Associate a strm_base instance with the + cobj handle rather than a null pointer. + (struct stdio_handle): Inherit struct strm_base. + (stdio_stream_destroy): Clean up the strm_base part. + (stdio_stream_mark): Mark the strm_base part. + (make_stdio_stream_common): Initialize the strm_base part. + (struct dir_handle): Inherit struct strm_base. + (dir_destroy): Clean up the strm_base part. + (dir_mark): Mark the strm_base part. + (make_dir_stream): Initialize the strm_base part. + (struct string_in): New structure. Replaces ad-hoc cons + cell used for string input streams. + (string_in_stream_mark): Mark new structure. + (string_in_get_line, string_in_get_char, string_in_unget_char, + string_in_get_prop, string_in_get_error, make_string_input_stream): + Convert to new structure. + (string_in_ops): Switch to stream_destroy_op. + (struct byte_input): Inherit struct strm_base. + (byte_in_stream_destroy): No need to check handle for null. + No need to set handle to null after freeing: gc does it. + Clean up the strm_base part. + (byte_in_ops): Switch to stream_mark_op. + (make_string_byte_input_stream): Initialize the strm_base part. + (struct string_output): Inherit struct strm_base. + (string_out_stream_destroy): No need to check handle for null + since the logic elsewhere has changed. + Clean up the strm_base part. + No need to set handle to null. + (string_out_ops): Switch to stream_mark_op. + (make_string_output_stream): Initialize the strm_base part. + (get_string_from_stream): Don't free the handle. + Null out the buffer so->buf whose ownership passes to the string. + (struct strlist_out): New structure. Replaces ad-hoc cons cell + used for string list output stream. + (strlist_mark): Renamed to strlist_out_mark. Mark the strm_base + part. + (strlist_out_put_string, strlist_out_put_char, + make_strlist_output_stream, get_list_from_stream): + Convert to new structure. + (strlist_out_ops): Switch to stream_destroy_op. + Follow rename of strlist_mark. + (struct cat_strm): New structure, replacing ad-hoc list pointer + +2015-07-29 Kaz Kylheku <kaz@kylheku.com> + * gc.c (finalize): Null out cobj handle after calling the destructor. This can catch some use-after-free errors. @@ -67,12 +67,41 @@ val from_start_k, from_current_k, from_end_k; val real_time_k, name_k, fd_k; val format_s; +void strm_base_init(struct strm_base *s) +{ + static struct strm_base init = { 0, 0, 0 }; + *s = init; +} + +void strm_base_cleanup(struct strm_base *s) +{ + (void) s; +} + +void strm_base_mark(struct strm_base *s) +{ + (void) s; +} + void stream_print_op(val stream, val out) { val name = stream_get_prop(stream, name_k); format(out, lit("#<~a ~p>"), name, stream, nao); } +void stream_destroy_op(val stream) +{ + struct strm_base *s = coerce(struct strm_base *, stream->co.handle); + strm_base_cleanup(s); + free(s); +} + +void stream_mark_op(val stream) +{ + struct strm_base *s = coerce(struct strm_base *, stream->co.handle); + strm_base_mark(s); +} + static noreturn void unimpl(val stream, val op) { uw_throwf(file_error_s, lit("~a: not supported by stream ~s\n"), @@ -239,8 +268,8 @@ void fill_stream_ops(struct strm_ops *ops) static struct strm_ops null_ops = strm_ops_init(cobj_ops_init(eq, stream_print_op, - cobj_destroy_stub_op, - cobj_mark_op, + stream_destroy_op, + stream_mark_op, cobj_hash_op), wli("null-stream"), null_put_string, null_put_char, null_put_byte, null_get_line, @@ -252,10 +281,13 @@ static struct strm_ops null_ops = val make_null_stream(void) { - return cobj(convert(mem_t *, 0), stream_s, &null_ops.cobj_ops); + struct strm_base *s = coerce(struct strm_base *, chk_malloc(sizeof *s)); + strm_base_init(s); + return cobj(convert(mem_t *, s), stream_s, &null_ops.cobj_ops); } struct stdio_handle { + struct strm_base a; FILE *f; val descr; val unget_c; @@ -287,12 +319,14 @@ static void stdio_stream_destroy(val stream) { struct stdio_handle *h = coerce(struct stdio_handle *, stream->co.handle); close_stream(stream, nil); + strm_base_cleanup(&h->a); free(h); } static void stdio_stream_mark(val stream) { struct stdio_handle *h = coerce(struct stdio_handle *, stream->co.handle); + strm_base_mark(&h->a); gc_mark(h->descr); gc_mark(h->mode); gc_mark(h->err); @@ -1036,6 +1070,7 @@ static val make_stdio_stream_common(FILE *f, val descr, struct cobj_ops *ops) { struct stdio_handle *h = coerce(struct stdio_handle *, chk_malloc(sizeof *h)); val stream = cobj(coerce(mem_t *, h), stream_s, ops); + strm_base_init(&h->a); h->f = f; h->descr = descr; h->unget_c = nil; @@ -1081,6 +1116,7 @@ static val make_pipevp_stream(FILE *f, val descr, pid_t pid) #endif struct dir_handle { + struct strm_base a; DIR *d; val err; }; @@ -1088,6 +1124,7 @@ struct dir_handle { static void dir_destroy(val stream) { struct dir_handle *h = coerce(struct dir_handle *, stream->co.handle); + strm_base_cleanup(&h->a); close_stream(stream, nil); free(h); } @@ -1095,6 +1132,7 @@ static void dir_destroy(val stream) static void dir_mark(val stream) { struct dir_handle *h = coerce(struct dir_handle *, stream->co.handle); + strm_base_mark(&h->a); gc_mark(h->err); } @@ -1169,15 +1207,24 @@ static struct strm_ops dir_ops = val make_dir_stream(DIR *dir) { struct dir_handle *h = coerce(struct dir_handle *, chk_malloc(sizeof *h)); + strm_base_init(&h->a); h->d = dir; h->err = nil; return cobj(coerce(mem_t *, h), stream_s, &dir_ops.cobj_ops); } +struct string_in { + struct strm_base a; + val string; + val pos; +}; + static void string_in_stream_mark(val stream) { - val stuff = coerce(val, stream->co.handle); - gc_mark(stuff); + struct string_in *s = coerce(struct string_in *, stream->co.handle); + strm_base_mark(&s->a); + gc_mark(s->string); + gc_mark(s->pos); } static val find_char(val string, val start, val ch) @@ -1197,14 +1244,12 @@ static val find_char(val string, val start, val ch) static val string_in_get_line(val stream) { - val pair = coerce(val, stream->co.handle); - val string = car(pair); - val pos = cdr(pair); + struct string_in *s = coerce(struct string_in *, stream->co.handle); - if (lt(pos, length_str(string))) { - val nlpos = find_char(string, pos, chr('\n')); - val result = sub_str(string, pos, nlpos); - set(cdr_l(pair), nlpos ? plus(nlpos, one) : length_str(string)); + if (lt(s->pos, length_str(s->string))) { + val nlpos = find_char(s->string, s->pos, chr('\n')); + val result = sub_str(s->string, s->pos, nlpos); + set(mkloc(s->pos, stream), nlpos ? plus(nlpos, one) : length_str(s->string)); return result; } @@ -1213,13 +1258,11 @@ static val string_in_get_line(val stream) static val string_in_get_char(val stream) { - val pair = coerce(val, stream->co.handle); - val string = car(pair); - val pos = cdr(pair); + struct string_in *s = coerce(struct string_in *, stream->co.handle); - if (lt(pos, length_str(string))) { - set(cdr_l(pair), plus(pos, one)); - return chr_str(string, pos); + if (lt(s->pos, length_str(s->string))) { + set(mkloc(s->pos, stream), plus(s->pos, one)); + return chr_str(s->string, s->pos); } return nil; @@ -1227,9 +1270,8 @@ static val string_in_get_char(val stream) static val string_in_unget_char(val stream, val ch) { - val pair = coerce(val, stream->co.handle); - val string = car(pair); - val pos = cdr(pair); + struct string_in *s = coerce(struct string_in *, stream->co.handle); + val pos = s->pos; if (pos == zero) uw_throwf(file_error_s, @@ -1237,35 +1279,31 @@ static val string_in_unget_char(val stream, val ch) pos = minus(pos, one); - if (chr_str(string, pos) != ch) + if (chr_str(s->string, pos) != ch) uw_throwf(file_error_s, lit("unget-char: ~s doesn't match the character that was read"), nao); - set(cdr_l(pair), plus(pos, one)); + set(mkloc(s->pos, stream), plus(pos, one)); return ch; } static val string_in_get_prop(val stream, val ind) { - if (ind == name_k) { - val pair = coerce(val, stream->co.handle); + struct string_in *s = coerce(struct string_in *, stream->co.handle); struct strm_ops *ops = coerce(struct strm_ops *, stream->co.ops); val name = static_str(ops->name); - - return format(nil, lit("~a ~s ~p"), name, car(pair), stream, nao); + return format(nil, lit("~a ~s ~p"), name, s->string, stream, nao); } + return nil; } static val string_in_get_error(val stream) { - val pair = coerce(val, stream->co.handle); - val string = car(pair); - val pos = cdr(pair); - - return if2(ge(pos, length_str(string)), t); + struct string_in *s = coerce(struct string_in *, stream->co.handle); + return if2(ge(s->pos, length_str(s->string)), t); } static val string_in_get_error_str(val stream) @@ -1276,7 +1314,7 @@ static val string_in_get_error_str(val stream) static struct strm_ops string_in_ops = strm_ops_init(cobj_ops_init(eq, stream_print_op, - cobj_destroy_stub_op, + stream_destroy_op, string_in_stream_mark, cobj_hash_op), wli("string-input-stream"), @@ -1295,10 +1333,15 @@ static struct strm_ops string_in_ops = val make_string_input_stream(val string) { - return cobj(coerce(mem_t *, cons(string, zero)), stream_s, &string_in_ops.cobj_ops); + struct string_in *s = coerce(struct string_in *, chk_malloc(sizeof *s)); + strm_base_init(&s->a); + s->string = string; + s->pos = zero; + return cobj(coerce(mem_t *, s), stream_s, &string_in_ops.cobj_ops); } struct byte_input { + struct strm_base a; unsigned char *buf; size_t size; size_t index; @@ -1307,13 +1350,10 @@ struct byte_input { static void byte_in_stream_destroy(val stream) { struct byte_input *bi = coerce(struct byte_input *, stream->co.handle); - - if (bi) { - free(bi->buf); - bi->buf = 0; - free(bi); - stream->co.handle = 0; - } + strm_base_cleanup(&bi->a); + free(bi->buf); + bi->buf = 0; + free(bi); } static val byte_in_get_byte(val stream) @@ -1353,7 +1393,7 @@ static struct strm_ops byte_in_ops = strm_ops_init(cobj_ops_init(eq, stream_print_op, byte_in_stream_destroy, - cobj_mark_op, + stream_mark_op, cobj_hash_op), wli("byte-input-stream"), 0, 0, 0, 0, 0, @@ -1372,6 +1412,7 @@ val make_string_byte_input_stream(val string) { struct byte_input *bi = coerce(struct byte_input *, chk_malloc(sizeof *bi)); unsigned char *utf8 = utf8_dup_to_uc(c_str(string)); + strm_base_init(&bi->a); bi->buf = utf8; bi->size = strlen(coerce(char *, utf8)); bi->index = 0; @@ -1380,6 +1421,7 @@ val make_string_byte_input_stream(val string) } struct string_output { + struct strm_base a; wchar_t *buf; size_t size; size_t fill; @@ -1392,12 +1434,10 @@ static void string_out_stream_destroy(val stream) { struct string_output *so = coerce(struct string_output *, stream->co.handle); - if (so) { - free(so->buf); - so->buf = 0; - free(so); - stream->co.handle = 0; - } + strm_base_cleanup(&so->a); + free(so->buf); + so->buf = 0; + free(so); } static int string_out_byte_callback(mem_t *ctx) @@ -1492,7 +1532,7 @@ static struct strm_ops string_out_ops = strm_ops_init(cobj_ops_init(eq, stream_print_op, string_out_stream_destroy, - cobj_mark_op, + stream_mark_op, cobj_hash_op), wli("string-output-stream"), string_out_put_string, @@ -1505,6 +1545,7 @@ static struct strm_ops string_out_ops = val make_string_output_stream(void) { struct string_output *so = coerce(struct string_output *, chk_malloc(sizeof *so)); + strm_base_init(&so->a); so->size = 128; so->buf = coerce(wchar_t *, chk_malloc(so->size * sizeof so->buf)); so->fill = 0; @@ -1525,40 +1566,47 @@ val get_string_from_stream(val stream) struct string_output *so = coerce(struct string_output *, stream->co.handle); val out = nil; - if (!so) + if (!so->buf) return out; while (so->head != so->tail) out = string_out_byte_flush(so, stream); - stream->co.handle = 0; - /* Trim to actual size */ so->buf = coerce(wchar_t *, chk_realloc(coerce(mem_t *, so->buf), (so->fill + 1) * sizeof *so->buf)); out = string_own(so->buf); - free(so); + so->buf = 0; return out; } else { type_assert (stream->co.ops == &string_in_ops.cobj_ops, (lit("~a is not a string stream"), stream, nao)); { - val pair = coerce(val, stream->co.handle); - return pair ? car(pair) : nil; + struct string_in *si = coerce(struct string_in *, stream->co.handle); + return si->string; } } } -static void strlist_mark(val stream) +struct strlist_out { + struct strm_base a; + val lines; + val strstream; +}; + +static void strlist_out_mark(val stream) { - val stuff = coerce(val, stream->co.handle); - gc_mark(stuff); + struct strlist_out *s = coerce(struct strlist_out *, stream->co.handle); + strm_base_mark(&s->a); + gc_mark(s->lines); + gc_mark(s->strstream); } static val strlist_out_put_string(val stream, val str) { - val cell = coerce(val, stream->co.handle); - cons_bind (lines, strstream, cell); + struct strlist_out *s = coerce(struct strlist_out *, stream->co.handle); + val lines = s->lines; + val strstream = s->strstream; for (;;) { val length = length_str(str); @@ -1577,35 +1625,37 @@ static val strlist_out_put_string(val stream, val str) strstream = make_string_output_stream(); } - set(car_l(cell), lines); - set(cdr_l(cell), strstream); + if (s->lines != lines) { + set(mkloc(s->lines, stream), lines); + set(mkloc(s->strstream, stream), strstream); + } return t; } static val strlist_out_put_char(val stream, val ch) { - val cell = coerce(val, stream->co.handle); - cons_bind (lines, strstream, cell); + struct strlist_out *s = coerce(struct strlist_out *, stream->co.handle); + val lines = s->lines; + val strstream = s->strstream; if (ch == chr('\n')) { push(get_string_from_stream(strstream), &lines); strstream = make_string_output_stream(); + set(mkloc(s->lines, stream), lines); + set(mkloc(s->strstream, stream), strstream); } else { put_char(ch, strstream); } - set(car_l(cell), lines); - set(cdr_l(cell), strstream); - return t; } static struct strm_ops strlist_out_ops = strm_ops_init(cobj_ops_init(eq, stream_print_op, - cobj_destroy_stub_op, - strlist_mark, + stream_destroy_op, + strlist_out_mark, cobj_hash_op), wli("strlist-output-stream"), strlist_out_put_string, @@ -1614,8 +1664,15 @@ static struct strm_ops strlist_out_ops = val make_strlist_output_stream(void) { - return cobj(coerce(mem_t *, cons(nil, make_string_output_stream())), - stream_s, &strlist_out_ops.cobj_ops); + struct strlist_out *s = coerce(struct strlist_out *, chk_malloc(sizeof *s)); + val stream; + val strstream = make_string_output_stream(); + strm_base_init(&s->a); + s->lines = nil; + s->strstream = nil; + stream = cobj(coerce(mem_t *, s), stream_s, &strlist_out_ops.cobj_ops); + s->strstream = strstream; + return stream; } val get_list_from_stream(val stream) @@ -1625,9 +1682,9 @@ val get_list_from_stream(val stream) (lit("~a is not a stream"), stream, nao)); if (stream->co.ops == &strlist_out_ops.cobj_ops) { - val cell = coerce(val, stream->co.handle); - cons_bind (lines, strstream, cell); - val stray = get_string_from_stream(strstream); + struct strlist_out *s = coerce(struct strlist_out *, stream->co.handle); + val stray = get_string_from_stream(s->strstream); + val lines = s->lines; if (!zerop(length_str(stray))) push(stray, &lines); return nreverse(lines); @@ -1636,18 +1693,24 @@ val get_list_from_stream(val stream) type_mismatch(lit("~s is not a string list stream"), stream); } +struct cat_strm { + struct strm_base a; + val streams; +}; + static void cat_stream_print(val stream, val out) { - val streams = coerce(val, stream->co.handle); + struct cat_strm *s = coerce(struct cat_strm *, stream->co.handle); struct strm_ops *ops = coerce(struct strm_ops *, stream->co.ops); val name = static_str(ops->name); - format(out, lit("#<~a ~s>"), name, streams, nao); + format(out, lit("#<~a ~s>"), name, s->streams, nao); } static val cat_get_line(val stream) { - val streams = coerce(val, stream->co.handle); + struct cat_strm *s = coerce(struct cat_strm *, stream->co.handle); + val streams = s->streams; while (streams) { val fs = first(streams); @@ -1656,7 +1719,7 @@ static val cat_get_line(val stream) return line; close_stream(fs, t); if ((streams = rest(streams)) != nil) - stream->co.handle = coerce(mem_t *, streams); + set(mkloc(s->streams, stream), streams); } return nil; @@ -1664,7 +1727,8 @@ static val cat_get_line(val stream) static val cat_get_char(val stream) { - val streams = coerce(val, stream->co.handle); + struct cat_strm *s = coerce(struct cat_strm *, stream->co.handle); + val streams = s->streams; while (streams) { val fs = first(streams); @@ -1673,7 +1737,7 @@ static val cat_get_char(val stream) return ch; close_stream(fs, t); if ((streams = rest(streams)) != nil) - stream->co.handle = coerce(mem_t *, streams); + set(mkloc(s->streams, stream), streams); } return nil; @@ -1681,7 +1745,8 @@ static val cat_get_char(val stream) static val cat_get_byte(val stream) { - val streams = coerce(val, stream->co.handle); + struct cat_strm *s = coerce(struct cat_strm *, stream->co.handle); + val streams = s->streams; while (streams) { val fs = first(streams); @@ -1690,7 +1755,7 @@ static val cat_get_byte(val stream) return byte; close_stream(fs, t); if ((streams = rest(streams)) != nil) - stream->co.handle = coerce(mem_t *, streams); + set(mkloc(s->streams, stream), streams); } return nil; @@ -1698,14 +1763,14 @@ static val cat_get_byte(val stream) static val cat_unget_byte(val stream, int byte) { - val streams = coerce(val, stream->co.handle); + struct cat_strm *s = coerce(struct cat_strm *, stream->co.handle); - if (!streams) { + if (!s->streams) { uw_throwf(file_error_s, lit("unget-byte on catenated stream ~a: stream list empty"), stream, nao); } else { - val stream = car(streams); + val stream = car(s->streams); return unget_byte(num_fast(byte), stream); } @@ -1714,54 +1779,57 @@ static val cat_unget_byte(val stream, int byte) static val cat_unget_char(val stream, val ch) { - val streams = coerce(val, stream->co.handle); + struct cat_strm *s = coerce(struct cat_strm *, stream->co.handle); - if (!streams) { + if (!s->streams) { uw_throwf(file_error_s, lit("unget-char on catenated stream ~a: stream list empty"), stream, nao); } else { - val stream = car(streams); - return unget_char(ch, stream ); + val stream = car(s->streams); + return unget_char(ch, stream); } } static val cat_get_prop(val stream, val ind) { - val streams = coerce(val, stream->co.handle); - if (streams) - return stream_get_prop(first(streams), ind); + struct cat_strm *s = coerce(struct cat_strm *, stream->co.handle); + + if (s->streams) + return stream_get_prop(first(s->streams), ind); + return nil; } static void cat_mark(val stream) { - val obj = coerce(val, stream->co.handle); - gc_mark(obj); + struct cat_strm *s = coerce(struct cat_strm *, stream->co.handle); + strm_base_mark(&s->a); + gc_mark(s->streams); } static val cat_get_error(val stream) { - val streams = coerce(val, stream->co.handle); - return if3(streams, get_error(first(streams)), t); + struct cat_strm *s = coerce(struct cat_strm *, stream->co.handle); + return if3(s->streams, get_error(first(s->streams)), t); } static val cat_get_error_str(val stream) { - val streams = coerce(val, stream->co.handle); - return if3(streams, get_error_str(first(streams)), lit("eof")); + struct cat_strm *s = coerce(struct cat_strm *, stream->co.handle); + return if3(s->streams, get_error_str(first(s->streams)), lit("eof")); } static val cat_clear_error(val stream) { - val streams = coerce(val, stream->co.handle); - return if2(streams, clear_error(first(streams))); + struct cat_strm *s = coerce(struct cat_strm *, stream->co.handle); + return if2(s->streams, clear_error(first(s->streams))); } static struct strm_ops cat_stream_ops = strm_ops_init(cobj_ops_init(eq, cat_stream_print, - cobj_destroy_stub_op, + stream_destroy_op, cat_mark, cobj_hash_op), wli("catenated-stream"), @@ -1780,7 +1848,10 @@ static struct strm_ops cat_stream_ops = val make_catenated_stream(val stream_list) { - return cobj(coerce(mem_t *, stream_list), stream_s, &cat_stream_ops.cobj_ops); + struct cat_strm *s = coerce(struct cat_strm *, chk_malloc(sizeof *s)); + strm_base_init(&s->a); + s->streams = stream_list; + return cobj(coerce(mem_t *, s), stream_s, &cat_stream_ops.cobj_ops); } val catenated_stream_p(val obj) @@ -1797,10 +1868,8 @@ val catenated_stream_push(val new_stream, val cat_stream) (lit("~a is not a stream"), cat_stream, nao)); { - val streams = coerce(val, cat_stream->co.handle); - loc l = mkloc(streams, cat_stream); - set(l, cons(new_stream, streams)); - cat_stream->co.handle = coerce(mem_t *, deref(l)); + struct cat_strm *s = coerce(struct cat_strm *, cat_stream->co.handle); + mpush(new_stream, mkloc(s->streams, cat_stream)); return nil; } } @@ -30,6 +30,12 @@ enum strm_whence { strm_end = SEEK_SET }; +struct strm_base { + unsigned int indent_on; + cnum indent_chars; + cnum column; +}; + struct strm_ops { struct cobj_ops cobj_ops; const wchli_t *name; @@ -78,8 +84,13 @@ extern val format_s; extern val stdin_s, stdout_s, stddebug_s, stderr_s, stdnull_s; +void strm_base_init(struct strm_base *s); +void strm_base_cleanup(struct strm_base *s); +void strm_base_mark(struct strm_base *s); void fill_stream_ops(struct strm_ops *ops); void stream_print_op(val stream, val out); +void stream_mark_op(val stream); +void stream_destroy_op(val stream); val make_null_stream(void); val make_stdio_stream(FILE *, val descr); val make_tail_stream(FILE *, val descr); @@ -43,6 +43,12 @@ #include "eval.h" #include "syslog.h" +struct syslog_strm { + struct strm_base a; + val prio; + val strstream; +}; + val prio_k; static struct strm_ops syslog_strm_ops; @@ -119,14 +125,18 @@ val closelog_wrap(void) static void syslog_mark(val stream) { + struct syslog_strm *s = coerce(struct syslog_strm *, stream->co.handle); + strm_base_mark(&s->a); + gc_mark(s->prio); + gc_mark(s->strstream); val stuff = coerce(val, stream->co.handle); gc_mark(stuff); } static val syslog_put_string(val stream, val str) { - val cell = coerce(val, stream->co.handle); - cons_bind (prio, strstream, cell); + struct syslog_strm *s = coerce(struct syslog_strm *, stream->co.handle); + val strstream = s->strstream; for (;;) { val length = length_str(str); @@ -141,51 +151,51 @@ static val syslog_put_string(val stream, val str) break; str = sub_str(str, plus(span_to_newline, num(1)), nil); - syslog_wrap(prio, lit("~a"), list(get_string_from_stream(strstream), nao)); + syslog_wrap(s->prio, lit("~a"), list(get_string_from_stream(strstream), nao)); strstream = make_string_output_stream(); } - set(cdr_l(cell), strstream); + set(mkloc(s->strstream, stream), strstream); return t; } static val syslog_put_char(val stream, val ch) { - val cell = coerce(val, stream->co.handle); - cons_bind (prio, strstream, cell); + struct syslog_strm *s = coerce(struct syslog_strm *, stream->co.handle); + val strstream = s->strstream; if (ch == chr('\n')) { - syslog_wrap(prio, lit("~a"), list(get_string_from_stream(strstream), nao)); + syslog_wrap(s->prio, lit("~a"), list(get_string_from_stream(strstream), nao)); strstream = make_string_output_stream(); } else { put_char(ch, strstream); } - set(cdr_l(cell), strstream); + set(mkloc(s->strstream, stream), strstream); return t; } static val syslog_put_byte(val stream, int ch) { - val cell = coerce(val, stream->co.handle); - cons_bind (prio, strstream, cell); + struct syslog_strm *s = coerce(struct syslog_strm *, stream->co.handle); + val strstream = s->strstream; if (ch == '\n') { - syslog_wrap(prio, lit("~a"), list(get_string_from_stream(strstream), nao)); + syslog_wrap(s->prio, lit("~a"), list(get_string_from_stream(strstream), nao)); strstream = make_string_output_stream(); } else { put_byte(num(ch), strstream); } - set(cdr_l(cell), strstream); + set(mkloc(s->strstream, stream), strstream); return t; } static val syslog_get_prop(val stream, val ind) { if (ind == prio_k) { - val cell = coerce(val, stream->co.handle); - return car(cell); + struct syslog_strm *s = coerce(struct syslog_strm *, stream->co.handle); + return s->prio; } else if (ind == name_k) { return lit("syslog"); } @@ -195,8 +205,8 @@ static val syslog_get_prop(val stream, val ind) static val syslog_set_prop(val stream, val ind, val prop) { if (ind == prio_k) { - val cell = coerce(val, stream->co.handle); - set(car_l(cell), prop); + struct syslog_strm *s = coerce(struct syslog_strm *, stream->co.handle); + set(mkloc(s->prio, stream), prop); return t; } return nil; @@ -219,6 +229,13 @@ static struct strm_ops syslog_strm_ops = val make_syslog_stream(val prio) { - return cobj(coerce(mem_t *, cons(prio, make_string_output_stream())), - stream_s, &syslog_strm_ops.cobj_ops); + struct syslog_strm *s = coerce(struct syslog_strm *, chk_malloc(sizeof *s)); + val stream; + val strstream = make_string_output_stream(); + strm_base_init(&s->a); + s->prio = prio; + s->strstream = nil; + stream = cobj(coerce(mem_t *, s), stream_s, &syslog_strm_ops.cobj_ops); + s->strstream = strstream; + return stream; } |