From b2d85ea84c930ebcfefc6449414ed64cd80e2f89 Mon Sep 17 00:00:00 2001 From: Tavian Barnes Date: Sat, 8 May 2021 11:57:06 -0400 Subject: util: Wrap getdelim() instead of open coding it --- util.c | 47 ++++++++++++++++++++--------------------------- util.h | 14 ++++++++++++++ 2 files changed, 34 insertions(+), 27 deletions(-) diff --git a/util.c b/util.c index 207e34d..d913b7d 100644 --- a/util.c +++ b/util.c @@ -266,31 +266,6 @@ bool is_nonexistence_error(int error) { return error == ENOENT || errno == ENOTDIR; } -/** Read a line from standard input. */ -static char *xgetline(void) { - char *line = dstralloc(0); - if (!line) { - return NULL; - } - - while (true) { - int c = fgetc(stdin); - if (c == '\n' || c == EOF) { - break; - } - - if (dstrapp(&line, c) != 0) { - goto error; - } - } - - return line; - -error: - dstrfree(line); - return NULL; -} - /** Compile and execute a regular expression for xrpmatch(). */ static int xrpregex(nl_item item, const char *response) { const char *pattern = nl_langinfo(item); @@ -339,9 +314,9 @@ static int xrpmatch(const char *response) { int ynprompt() { fflush(stderr); - char *line = xgetline(); + char *line = xgetdelim(stdin, '\n'); int ret = line ? xrpmatch(line) : -1; - dstrfree(line); + free(line); return ret; } @@ -433,3 +408,21 @@ char *xconfstr(int name) { return str; } + +char *xgetdelim(FILE *file, char delim) { + char *chunk = NULL; + size_t n = 0; + ssize_t len = getdelim(&chunk, &n, delim, file); + if (len >= 0) { + if (chunk[len] == delim) { + chunk[len] = '\0'; + } + return chunk; + } else { + free(chunk); + if (!ferror(file)) { + errno = 0; + } + return NULL; + } +} diff --git a/util.h b/util.h index 1a34fba..be38db5 100644 --- a/util.h +++ b/util.h @@ -26,6 +26,7 @@ #include #include #include +#include #include // Some portability concerns @@ -274,4 +275,17 @@ size_t xwrite(int fd, const void *buf, size_t nbytes); */ char *xconfstr(int name); +/** + * Convenience wrapper for getdelim(). + * + * @param file + * The file to read. + * @param delim + * The delimiter character to split on. + * @return + * The read chunk (without the delimiter), allocated with malloc(). + * NULL is returned on error (errno != 0) or end of file (errno == 0). + */ +char *xgetdelim(FILE *file, char delim); + #endif // BFS_UTIL_H -- cgit v1.2.3