[Toybox] [PATCH] Make yesno printf-like.
enh
enh at google.com
Tue Sep 1 18:35:39 PDT 2015
Make yesno printf-like.
In addition to making most existing code slightly simpler, this will
let us move "if (!isatty(0)) return def;" into yesno so we can avoid
printing a prompt in non-interactive situations.
diff --git a/lib/lib.c b/lib/lib.c
index c16cffe..78d8742 100644
--- a/lib/lib.c
+++ b/lib/lib.c
@@ -630,12 +630,17 @@ void base64_init(char *p)
*(p++) = '/';
}
-int yesno(char *prompt, int def)
+int yesno(int def, char *prompt, ...)
{
char buf;
- fprintf(stderr, "%s (%c/%c):", prompt, def ? 'Y' : 'y', def ? 'n' : 'N');
+ va_list va;
+ va_start(va, prompt);
+ vfprintf(stderr, prompt, va);
+ va_end(va);
+ fprintf(stderr, " (%c/%c):", def ? 'Y' : 'y', def ? 'n' : 'N');
fflush(stderr);
+
while (fread(&buf, 1, 1, stdin)) {
int new;
diff --git a/lib/lib.h b/lib/lib.h
index 17a4a97..25b5bc2 100644
--- a/lib/lib.h
+++ b/lib/lib.h
@@ -176,7 +176,7 @@ void delete_tempfile(int fdin, int fdout, char **tempname);
void replace_tempfile(int fdin, int fdout, char **tempname);
void crc_init(unsigned int *crc_table, int little_endian);
void base64_init(char *p);
-int yesno(char *prompt, int def);
+int yesno(int def, char *prompt, ...) printf_format;
#define HR_SPACE 1
#define HR_B 2
int human_readable(char *buf, unsigned long long num, int style);
diff --git a/toys/lsb/killall.c b/toys/lsb/killall.c
index 478f761..2aefc8b 100644
--- a/toys/lsb/killall.c
+++ b/toys/lsb/killall.c
@@ -40,8 +40,7 @@ static int kill_process(pid_t pid, char *name)
if (pid == TT.cur_pid) return 0;
if (toys.optflags & FLAG_i) {
- snprintf(toybuf, sizeof(toybuf), "Signal %s(%d) ?", name, (int)pid);
- if (!yesno(toybuf, 0)) return 0;
+ if (!yesno(0, "Signal %s(%d) ?", name, (int)pid)) return 0;
}
errno = 0;
diff --git a/toys/pending/crontab.c b/toys/pending/crontab.c
index 35f6d65..f0aa160 100644
--- a/toys/pending/crontab.c
+++ b/toys/pending/crontab.c
@@ -317,9 +317,8 @@ RETRY:
}
printf("%s: installing new crontab\n", toys.which->name);
if (parse_crontab(tname)) {
- snprintf(toybuf, sizeof(toybuf), "errors in crontab file, can't install.\n"
- "Do you want to retry the same edit? ");
- if (!yesno(toybuf, 0)) {
+ if (!yesno(0, "errors in crontab file, can't install.\n"
+ "Do you want to retry the same edit? ")) {
error_msg("edits left in '%s'", tname);
return;
}
diff --git a/toys/posix/cp.c b/toys/posix/cp.c
index 5a55f40..a9c1b8d 100644
--- a/toys/posix/cp.c
+++ b/toys/posix/cp.c
@@ -173,7 +173,7 @@ int cp_node(struct dirtree *try)
fprintf(stderr, "%s: overwrite '%s'", toys.which->name,
s = dirtree_path(try, 0));
free(s);
- if (!yesno("", 1)) return 0;
+ if (!yesno(1, "")) return 0;
}
}
@@ -380,8 +380,8 @@ void cp_main(void)
if (!stat(TT.destname, &st)
&& ((toys.optflags & FLAG_i) || !(st.st_mode & 0222)))
{
- fprintf(stderr, "%s: overwrite '%s'", toys.which->name, TT.destname);
- if (!yesno("", 1)) rc = 0;
+ if (!yesno(1, "%s: overwrite '%s'", toys.which->name, TT.destname))
+ rc = 0;
else unlink(TT.destname);
}
}
diff --git a/toys/posix/find.c b/toys/posix/find.c
index 99cf5e2..0f064ca 100644
--- a/toys/posix/find.c
+++ b/toys/posix/find.c
@@ -421,10 +421,7 @@ static int do_find(struct dirtree *new)
if (aa->dir) aa->prev = (void *)1;
if (*s == 'o') {
- char *prompt = xmprintf("[%s] %s", ss1, name);
- test = yesno(prompt, 0);
- free(prompt);
- if (!test) {
+ if (!yesno(0, "[%s] %s", ss1, name)) {
free(name);
goto cont;
}
diff --git a/toys/posix/rm.c b/toys/posix/rm.c
index 5523a98..e5c5ae2 100644
--- a/toys/posix/rm.c
+++ b/toys/posix/rm.c
@@ -39,8 +39,7 @@ static int do_rm(struct dirtree *try)
&& (!S_ISLNK(try->st.st_mode) && faccessat(fd, try->name, W_OK, 0))) or++;
if (!(dir && try->again) && ((or && isatty(0)) || (flags & FLAG_i))) {
char *s = dirtree_path(try, 0);
- fprintf(stderr, "rm %s%s", or ? "ro " : "", dir ? "dir " : "");
- or = yesno(s, 0);
+ or = yesno(0, "rm %s%s%s", or ? "ro " : "", dir ? "dir " : "", s);
free(s);
if (!or) goto nodelete;
}
@@ -58,8 +57,7 @@ static int do_rm(struct dirtree *try)
if (flags & FLAG_i) {
char *s = dirtree_path(try, 0);
// This is the section 2(d) prompt. (Yes, posix says to prompt twice.)
- fprintf(stderr, "rmdir ");
- or = yesno(s, 0);
+ or = yesno(0, "rmdir %s", s);
free(s);
if (!or) goto nodelete;
}
diff --git a/www/code.html b/www/code.html
index a1c08ef..61c9847 100644
--- a/www/code.html
+++ b/www/code.html
@@ -768,7 +768,7 @@ struct passwd *xgetpwnam(char *name)</b></p>
<li><b>void replace_tempfile(int fdin, int fdout, char **tempname)</b></li>
<li><b>void crc_init(unsigned int *crc_table, int little_endian)</b></li>
<li><b>int terminal_size(unsigned *xx, unsigned *yy)</b></li>
-<li><b>int yesno(char *prompt, int def)</b></li>
+<li><b>int yesno(int def, char *prompt, ...)</b></li>
<li><b>void generic_signal(int sig)</b></li>
<li><b>void sigatexit(void *handler)</b></li>
<li><b>int sig_to_num(char *pidstr)</b></li>
More information about the Toybox
mailing list