Added code for `--retry-input' in question()
This commit is contained in:
parent
aeeaa3524c
commit
b3521680fd
1 changed files with 92 additions and 29 deletions
|
@ -1710,6 +1710,14 @@ static int question(short preset, const char *format, va_list args)
|
||||||
FILE *stream;
|
FILE *stream;
|
||||||
int fd_in = fileno(stdin);
|
int fd_in = fileno(stdin);
|
||||||
|
|
||||||
|
va_list args_copy;
|
||||||
|
int format_len;
|
||||||
|
/* No need to initialize:
|
||||||
|
* the other calls also print a termination character */
|
||||||
|
char prompt_cache_stack[256];
|
||||||
|
char *prompt_cache = prompt_cache_stack;
|
||||||
|
size_t prompt_cache_size = sizeof(prompt_cache_stack);
|
||||||
|
|
||||||
if(config->noconfirm) {
|
if(config->noconfirm) {
|
||||||
stream = stdout;
|
stream = stdout;
|
||||||
} else {
|
} else {
|
||||||
|
@ -1717,12 +1725,63 @@ static int question(short preset, const char *format, va_list args)
|
||||||
stream = stderr;
|
stream = stderr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Cache prompt, because we can't call v*printf() multiple times
|
||||||
|
* on the same arguments. */
|
||||||
|
/* Copy args so we can retry when the buffer is too small */
|
||||||
|
va_copy(args_copy, args);
|
||||||
|
|
||||||
|
/* Don't ask me why v*printf() returns an Integer instead of a long */
|
||||||
|
format_len = vsnprintf(
|
||||||
|
prompt_cache,
|
||||||
|
prompt_cache_size,
|
||||||
|
format, args);
|
||||||
|
|
||||||
|
/* Something has gone wrong */
|
||||||
|
if (format_len < 1) {
|
||||||
|
pm_printf(ALPM_LOG_ERROR, _("vsnprintf failure: Failed to cache prompt: %s\n"), strerror(errno));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Buffer is too small */
|
||||||
|
if ((size_t)format_len + 1 > prompt_cache_size) {
|
||||||
|
prompt_cache = malloc(format_len + 1);
|
||||||
|
prompt_cache_size = format_len + 1;
|
||||||
|
if (prompt_cache == 0) {
|
||||||
|
pm_printf(ALPM_LOG_ERROR, _("malloc failure: could not allocate %i bytes\n"), format_len + 1);
|
||||||
|
|
||||||
|
va_end(args_copy);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
format_len = vsnprintf(prompt_cache, prompt_cache_size, format, args_copy);
|
||||||
|
/* Something has gone wrong */
|
||||||
|
if (format_len < 1) {
|
||||||
|
pm_printf(ALPM_LOG_ERROR, _("vsnprintf failure: Failed to cache prompt: %s\n"), strerror(errno));
|
||||||
|
|
||||||
|
va_end(args_copy);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Just in case */
|
||||||
|
if ((size_t)format + 1 != prompt_cache_size) {
|
||||||
|
pm_printf(ALPM_LOG_ERROR, _("vsnprintf failure: Failed to cache prompt: Required size: %zu -> %i bytes\n"), prompt_cache_size, format_len + 1);
|
||||||
|
|
||||||
|
va_end(args_copy);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We can free the args-copy now */
|
||||||
|
va_end(args_copy);
|
||||||
|
|
||||||
|
/* Prompt the user at least once before exiting */
|
||||||
|
do {
|
||||||
/* ensure all text makes it to the screen before we prompt the user */
|
/* ensure all text makes it to the screen before we prompt the user */
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
fflush(stderr);
|
fflush(stderr);
|
||||||
|
|
||||||
fputs(config->colstr.colon, stream);
|
fputs(config->colstr.colon, stream);
|
||||||
vfprintf(stream, format, args);
|
fputs(prompt_cache, stream);
|
||||||
|
|
||||||
if(preset) {
|
if(preset) {
|
||||||
fprintf(stream, " %s ", _("[Y/n]"));
|
fprintf(stream, " %s ", _("[Y/n]"));
|
||||||
|
@ -1756,8 +1815,12 @@ static int question(short preset, const char *format, va_list args)
|
||||||
return 1;
|
return 1;
|
||||||
} else if(mbscasecmp(response, _("N")) == 0 || mbscasecmp(response, _("NO")) == 0) {
|
} else if(mbscasecmp(response, _("N")) == 0 || mbscasecmp(response, _("NO")) == 0) {
|
||||||
return 0;
|
return 0;
|
||||||
|
} else
|
||||||
|
/* Emulate same behaviour as multiselect_question() and select_question() */
|
||||||
|
fprintf(stream, _("invalid input: prompt requires `%s' or `%s'\n\n"), _("Y"), _("N"));
|
||||||
}
|
}
|
||||||
}
|
} while (config->retry_input);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue