#include #include uint verbose_level; void __attribute__((noreturn)) error(const char* fmt, ...) { va_list ap; va_start(ap, fmt); vfprintf(stderr, fmt, ap); exit(EXIT_FAILURE); } int verbose(uint level, const char* fmt, ...) { int ret = 0; va_list ap; if (verbose_level >= level) { va_start(ap, fmt); vprintf(fmt, ap); } return ret; } bool ask_user_bool(tristate_t auto_response, const char* fmt, ...) { va_list ap; char prompt[256]; char* line; size_t len; int ret; bool answer; va_start(ap, fmt); vsnprintf(prompt, sizeof(prompt), fmt, ap); va_end(ap); again: printf("%s [y/n]? ", prompt); if (auto_response != t_none) { answer = (auto_response == t_true); printf("%s\n", (answer ? "y" : "n")); return answer; } line = NULL; len = 0; getline(&line, &len, stdin); if (ret > 0) { switch (line[0]) { case 'y': case 'Y': answer = true; break; case 'n': case 'N': answer = false; break; default: ret = -1; } } free(line); if (ret <= 0) { goto again; } return answer; }