summaryrefslogtreecommitdiffstats
path: root/util.c
diff options
context:
space:
mode:
authorTavian Barnes <tavianator@tavianator.com>2017-07-15 22:56:11 -0400
committerTavian Barnes <tavianator@tavianator.com>2017-07-15 22:56:11 -0400
commitdb2fa0e1059a2426a1afa4fc0c97d6f85f176641 (patch)
treebc3684b2e776af6ab55560aa0174c099c7f01196 /util.c
parent7b1adcebf65d2131c4d324e73a3e3eace6b2ec28 (diff)
downloadbfs-db2fa0e1059a2426a1afa4fc0c97d6f85f176641.tar.xz
Handle yes/no prompts correctly according to the locale
Diffstat (limited to 'util.c')
-rw-r--r--util.c72
1 files changed, 72 insertions, 0 deletions
diff --git a/util.c b/util.c
index e64157b..81eeda0 100644
--- a/util.c
+++ b/util.c
@@ -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(&regex, pattern, REG_EXTENDED);
+ if (ret != 0) {
+ return ret;
+ }
+
+ ret = regexec(&regex, response, 0, NULL, 0);
+ regfree(&regex);
+ 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;
+}