diff options
Diffstat (limited to 'dynstr.c')
-rw-r--r-- | dynstr.c | 84 |
1 files changed, 84 insertions, 0 deletions
@@ -369,3 +369,87 @@ Dynstr *dynstr_read(int file, size_t size) return read_helper(read_callback, NULL, file, size); } + +static Dynstr *readline_helper(int (*callback)(FILE *, int), FILE *f, int fd) +{ + Dynstr *line; + Dynstr *temp1; + Dynstr *temp2; + int c; + unsigned char byte; + + line = dynstr_new_empty(); + + for (;;) { + temp1 = NULL; + temp2 = NULL; + + c = callback(f, fd); + if (c == -1) + goto error; + else if (c == -2) + break; + + byte = c; + temp1 = dynstr_new_from_constant_memory(&byte, 1); + if (temp1 == NULL) + goto error; + temp2 = dynstr_cat(line, temp1, NULL); + dynstr_free(temp1); + dynstr_free(line); + line = temp2; + + if (c == '\n') + break; + } + + return line; + +error: + dynstr_free(line); + dynstr_free(temp1); + dynstr_free(temp2); + return NULL; +} + + +static int freadline_callback(FILE *f, int fd) +{ + int c; + + c = getc(f); + if (c == EOF && ferror(f)) + return -1; + else if (c == EOF) + return -2; + else + return c; +} + + +Dynstr *dynstr_freadline(FILE *file) +{ + return readline_helper(freadline_callback, file, -1); +} + + +static int readline_callback(FILE *f, int fd) +{ + unsigned char c; + int n; + + n = read(fd, &c, 1); + if (n == 0) + return -2; + else if (n == -1) + return -1; + else + return c; +} + + +Dynstr *dynstr_readline(int file) +{ + return readline_helper(readline_callback, NULL, file); +} + |