summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohannes Weiner <hannes@cmpxchg.org>2010-07-14 13:10:35 +0200
committerJohannes Weiner <hannes@cmpxchg.org>2010-07-14 13:10:35 +0200
commit1945bdfab15e082b9748829916e7a9cfe874fd99 (patch)
tree5b9c6afde2f90c26d25cff8588ae94a0225b69a9
parent4315dbad531a7cb20734ad0b66230770d12ef71a (diff)
lib/io: add (io:readline)
Signed-off-by: Johannes Weiner <hannes@cmpxchg.org>
-rw-r--r--lib/io.c34
1 files changed, 34 insertions, 0 deletions
diff --git a/lib/io.c b/lib/io.c
index d452238..62980d5 100644
--- a/lib/io.c
+++ b/lib/io.c
@@ -129,11 +129,45 @@ static sheep_t write(struct sheep_vm *vm, unsigned int nr_args)
return sheep_make_number(vm, nr_bytes);
}
+/* (readline file) */
+static sheep_t readline(struct sheep_vm *vm, unsigned int nr_args)
+{
+ char *str = NULL, *endp = NULL, buf[512];
+ unsigned long len = 0;
+ struct file *file;
+
+ if (sheep_unpack_stack(vm, nr_args, "T", &file_type, &file))
+ return NULL;
+
+ if (!file->filp) {
+ sheep_error(vm, "file is already closed");
+ return NULL;
+ }
+
+ while (!endp && fgets(buf, sizeof(buf), file->filp)) {
+ unsigned long delta;
+
+ endp = strpbrk(buf, "\r\n");
+ if (!endp)
+ delta = strlen(buf);
+ else
+ delta = endp - buf;
+
+ str = sheep_realloc(str, len + delta + 1);
+ strncpy(str + len, buf, delta);
+ len += delta;
+ }
+ str[len] = 0;
+
+ return __sheep_make_string(vm, str, len);
+}
+
int init(struct sheep_vm *vm, struct sheep_module *module)
{
sheep_module_function(vm, module, "open", open);
sheep_module_function(vm, module, "close", close);
sheep_module_function(vm, module, "read", read);
sheep_module_function(vm, module, "write", write);
+ sheep_module_function(vm, module, "readline", readline);
return 0;
}