diff options
author | Tavian Barnes <tavianator@tavianator.com> | 2017-07-15 22:56:11 -0400 |
---|---|---|
committer | Tavian Barnes <tavianator@tavianator.com> | 2017-07-15 22:56:11 -0400 |
commit | db2fa0e1059a2426a1afa4fc0c97d6f85f176641 (patch) | |
tree | bc3684b2e776af6ab55560aa0174c099c7f01196 /util.c | |
parent | 7b1adcebf65d2131c4d324e73a3e3eace6b2ec28 (diff) | |
download | bfs-db2fa0e1059a2426a1afa4fc0c97d6f85f176641.tar.xz |
Handle yes/no prompts correctly according to the locale
Diffstat (limited to 'util.c')
-rw-r--r-- | util.c | 72 |
1 files changed, 72 insertions, 0 deletions
@@ -11,10 +11,13 @@ #include "util.h" #include "bftw.h" +#include "dstring.h" #include <errno.h> #include <fcntl.h> +#include <langinfo.h> #include <regex.h> #include <stdarg.h> +#include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/stat.h> @@ -314,3 +317,72 @@ enum bftw_typeflag dirent_to_typeflag(const struct dirent *de) { return BFTW_UNKNOWN; } + +/** Read a line from standard input. */ +static char *xgetline() { + char *line = dstralloc(0); + if (!line) { + return NULL; + } + + while (true) { + int c = getchar(); + 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); + if (!pattern) { + return REG_BADPAT; + } + + regex_t regex; + int ret = regcomp(®ex, pattern, REG_EXTENDED); + if (ret != 0) { + return ret; + } + + ret = regexec(®ex, response, 0, NULL, 0); + regfree(®ex); + return ret; +} + +/** Check if a response is affirmative or negative. */ +static int xrpmatch(const char *response) { + int ret = xrpregex(NOEXPR, response); + if (ret == 0) { + return 0; + } else if (ret != REG_NOMATCH) { + return -1; + } + + ret = xrpregex(YESEXPR, response); + if (ret == 0) { + return 1; + } else { + return -1; + } +} + +int ynprompt() { + fflush(stderr); + + char *line = xgetline(); + int ret = line ? xrpmatch(line) : -1; + dstrfree(line); + return ret; +} |