diff options
-rw-r--r-- | buf.c | 4 | ||||
-rw-r--r-- | buf.h | 4 | ||||
-rw-r--r-- | stream.c | 30 | ||||
-rw-r--r-- | stream.h | 1 | ||||
-rw-r--r-- | txr.1 | 23 |
5 files changed, 60 insertions, 2 deletions
@@ -397,7 +397,7 @@ val buf_put_buf(val dbuf, val sbuf, val pos) return sbuf; } -static void buf_put_bytes(val buf, val pos, mem_t *ptr, cnum size, val self) +void buf_put_bytes(val buf, val pos, mem_t *ptr, cnum size, val self) { struct buf *b = buf_handle(buf, self); cnum p = buf_check_index(b, pos, self); @@ -589,7 +589,7 @@ val buf_put_cptr(val buf, val pos, val cptr) return cptr; } -static void buf_get_bytes(val buf, val pos, mem_t *ptr, cnum size, val self) +void buf_get_bytes(val buf, val pos, mem_t *ptr, cnum size, val self) { struct buf *b = buf_handle(buf, self); cnum p = buf_check_index(b, pos, self); @@ -41,6 +41,8 @@ val replace_buf(val buf, val items, val from, val to); val buf_list(val list); val buf_put_buf(val dbuf, val sbuf, val pos); +void buf_put_bytes(val buf, val pos, mem_t *ptr, cnum size, val self); + #if HAVE_I8 val buf_put_i8(val buf, val pos, val num); val buf_put_u8(val buf, val pos, val num); @@ -73,6 +75,8 @@ val buf_put_float(val buf, val pos, val num); val buf_put_double(val buf, val pos, val num); val buf_put_cptr(val buf, val pos, val cptr); +void buf_get_bytes(val buf, val pos, mem_t *ptr, cnum size, val self); + #if HAVE_I8 val buf_get_i8(val buf, val pos); val buf_get_u8(val buf, val pos); @@ -3038,6 +3038,35 @@ val fill_buf_adjust(val buf, val pos_in, val stream_in) return readpos; } +val get_line_as_buf(val stream_in) +{ + val self = lit("get-line-as-buf"); + val stream = default_arg(stream_in, std_input); + struct strm_ops *ops = coerce(struct strm_ops *, + cobj_ops(self, stream, stream_s)); + val buf = make_buf(zero, nil, num_fast(128)); + unsigned char bytes[128]; + size_t count = 0; + + for (;;) { + val b = ops->get_byte(stream); + if (b == nil || b == num('\n')) + break; + bytes[count++] = c_num(b); + + if (count == sizeof bytes) { + buf_put_bytes(buf, length_buf(buf), bytes, count, self); + count = 0; + } + } + + if (count > 0) + buf_put_bytes(buf, length_buf(buf), bytes, count, self); + + buf_trim(buf); + return buf; +} + struct fmt { size_t minsize; const char *dec; @@ -4964,6 +4993,7 @@ void stream_init(void) reg_fun(unget_byte_s, func_n2o(unget_byte, 1)); reg_fun(put_buf_s, func_n3o(put_buf, 1)); reg_fun(fill_buf_s, func_n3o(fill_buf, 1)); + reg_fun(intern(lit("get-line-as-buf"), user_package), func_n1o(get_line_as_buf, 0)); reg_fun(intern(lit("fill-buf-adjust"), user_package), func_n3o(fill_buf_adjust, 1)); reg_fun(intern(lit("flush-stream"), user_package), func_n1o(flush_stream, 0)); reg_fun(intern(lit("seek-stream"), user_package), func_n3(seek_stream)); @@ -199,6 +199,7 @@ val unget_byte(val byte, val stream); val put_buf(val buf, val pos, val stream); val fill_buf(val buf, val pos, val stream); val fill_buf_adjust(val buf, val pos, val stream); +val get_line_as_buf(val stream); val vformat(val stream, val string, va_list); val vformat_to_string(val string, va_list); val format(val stream, val string, ...); @@ -25120,6 +25120,29 @@ Finally, if the operation succeeds, then .code fill-buf-adjust adjusts the length of the buffer to match the position that is returned. +.coNP Function @ get-line-as-buf +.synb +.mets (get-line-as-buf <> [ stream ]) +.syne +.desc +The +.code get-line-as-buf +reads bytes from +.meta stream +as if using the +.code get-byte +function, until either a the newline character is encountered, or else the end +of input is encountered. The bytes which are read, exclusive of the newline +character, are returned in a new buffer object. The newline character, if it +occurs, is consumed. + +If +.meta stream +is omitted, it defaults to +.codn *stdin* . + +The stream is required to support byte input. + .coNP Functions @ file-get-buf and @ command-get-buf .synb .mets (file-get-buf < name >> [ max-bytes <> [ skip-bytes ]]) |