aboutsummaryrefslogtreecommitdiff
path: root/libbutl/prompt.cxx
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2018-07-07 12:34:08 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2018-07-07 12:34:08 +0200
commit726f4573a5d183a685e0a1032a3e247e3b47482e (patch)
treea92ee55bdea255789df662c77063ee89ccca6eff /libbutl/prompt.cxx
parentfb9b318a77ad9364aa2303679c0b84d2d1bdb055 (diff)
Move prompt facility from bpkg to libbutl
Diffstat (limited to 'libbutl/prompt.cxx')
-rw-r--r--libbutl/prompt.cxx74
1 files changed, 74 insertions, 0 deletions
diff --git a/libbutl/prompt.cxx b/libbutl/prompt.cxx
new file mode 100644
index 0000000..52442b2
--- /dev/null
+++ b/libbutl/prompt.cxx
@@ -0,0 +1,74 @@
+// file : libbutl/prompt.cxx -*- C++ -*-
+// copyright : Copyright (c) 2014-2018 Code Synthesis Ltd
+// license : MIT; see accompanying LICENSE file
+
+#ifndef __cpp_modules
+#include <libbutl/prompt.mxx>
+#endif
+
+#ifndef __cpp_lib_modules
+#include <string>
+
+#include <iostream>
+#endif
+
+// Other includes.
+
+#ifdef __cpp_modules
+module butl.prompt;
+
+// Only imports additional to interface.
+#ifdef __clang__
+#ifdef __cpp_lib_modules
+import std.core;
+import std.io;
+#endif
+#endif
+
+import butl.diagnostics;
+#else
+#include <libbutl/diagnostics.mxx> // diag_stream
+#endif
+
+using namespace std;
+
+namespace butl
+{
+ bool
+ yn_prompt (const string& prompt, char def)
+ {
+ // Writing a robust Y/N prompt is more difficult than one would expect.
+ //
+ string a;
+ do
+ {
+ *diag_stream << prompt << ' ';
+
+ // getline() will set the failbit if it failed to extract anything,
+ // not even the delimiter and eofbit if it reached eof before seeing
+ // the delimiter.
+ //
+ getline (cin, a);
+
+ bool f (cin.fail ());
+ bool e (cin.eof ());
+
+ if (f || e)
+ *diag_stream << endl; // Assume no delimiter (newline).
+
+ if (f)
+ throw ios_base::failure ("unable to read y/n answer from stdout");
+
+ if (a.empty () && def != '\0')
+ {
+ // Don't treat eof as the default answer. We need to see the actual
+ // newline.
+ //
+ if (!e)
+ a = def;
+ }
+ } while (a != "y" && a != "n");
+
+ return a == "y";
+ }
+}