00001 // ======================================================================== // 00002 // // 00003 // File : user.cpp // 00004 // Purpose : // 00005 // Time-stamp: <Wed Nov/13/2002 06:10 MET Coder@ReallySoft.de> // 00006 // // 00007 // (C) February 2002 by Ralf Westram // 00008 // // 00009 // Permission to use, copy, modify, distribute and sell this software // 00010 // and its documentation for any purpose is hereby granted without fee, // 00011 // provided that the above copyright notice appear in all copies and // 00012 // that both that copyright notice and this permission notice appear // 00013 // in supporting documentation. // 00014 // // 00015 // Ralf Westram makes no representations about the suitability of this // 00016 // software for any purpose. It is provided "as is" without express or // 00017 // implied warranty. // 00018 // // 00019 // ======================================================================== // 00020 00021 #include "user.h" 00022 #include <Tools.h> 00023 #include <rs_assert.h> 00024 #include <Err.h> 00025 00026 using namespace std; 00027 using namespace rs; 00028 using namespace rs::str; 00029 using namespace rs::err; 00030 00031 #define OUT cerr 00032 #define IN cin 00033 00034 namespace rs { 00035 namespace user { 00036 // -------------------------------------------------------------- 00037 // string ask(const string& question, bool allow_empty) 00038 // -------------------------------------------------------------- 00039 string ask(const string& question, bool allow_empty) { 00040 string answer; 00041 if (question.length()) OUT << question << endl; 00042 while (1) { 00043 getline(IN, answer, '\n'); 00044 if (allow_empty || answer.length()) break; 00045 OUT << "Enter your answer and press ENTER (or press Ctrl-C to abort)" << endl; 00046 }; 00047 00048 return answer; 00049 } 00050 00051 // ------------------------------------------------------------------ 00052 // bool ask_yn(string question, const char *default_answer) 00053 // ------------------------------------------------------------------ 00054 bool ask_yn(string question, const char *default_answer) { 00055 while (1) { 00056 string answer = ask(default_answer ? (question+" ["+default_answer+"]") : question, true); 00057 if (answer.empty() && default_answer) answer = default_answer; 00058 strlwr(answer); 00059 00060 if (answer == "yes" || answer == "y") return true; 00061 if (answer == "no" || answer == "n") return false; 00062 question = "Please answer with yes or no (y/n)"; 00063 } 00064 } 00065 // ------------------------------------------------------------ 00066 // int ask_number(string question, int low, int high) 00067 // ------------------------------------------------------------ 00068 int ask_number(string question, int low, int high) { 00069 int num = 0; 00070 assert(low <= high); 00071 while (1) { 00072 string answer = ask(question, true); 00073 num = atoi(answer.c_str()); 00074 00075 if (num >= low && num <= high) break; 00076 question = strf("Please enter a number between %i and %i", low, high); 00077 } 00078 return num; 00079 } 00080 // --------------------------------------------------------------------------- 00081 // size_t choose(const string& title, const vector<string>& answers) 00082 // --------------------------------------------------------------------------- 00083 size_t choose(const string& title, const vector<string>& answers) { 00084 int count = 1; 00085 int max_width = 0; 00086 00087 for (vector<string>::const_iterator s = answers.begin(); s != answers.end(); ++s, ++count) { 00088 int width = 3+(count<10 ? 1 : (count<100 ? 2 : 3)) + s->length() + 1; 00089 if (width>max_width) max_width = width; 00090 } 00091 00092 size_t size = answers.size(); 00093 int rows = size; 00094 int columns = 1; 00095 00096 int tty_rows = 50; // @@@ how can I detect the real TTY size ? 00097 int tty_columns = 80; 00098 00099 if (rows>(tty_rows-3)) { 00100 columns = tty_columns/max_width; 00101 rows = size/columns + !!(size%columns); 00102 } 00103 00104 OUT << title; 00105 for (count = 0; count < rows; ++count) { 00106 OUT << '\n'; 00107 for (int c = 0; c<columns; ++c) { 00108 unsigned idx = count + c*rows; 00109 if (idx<size) { 00110 OUT << strf("%-*s", max_width, strf("(%i) %s", idx+1, answers[idx].c_str()).c_str()); 00111 } 00112 } 00113 } 00114 00115 OUT << endl; 00116 00117 if (!size) throw InternalError("No choices to choose from"); 00118 if (size == 1) { 00119 OUT << "[Only one choice => autoselected!]\n"; 00120 return 1; 00121 } 00122 return ask_number("", 1, size); 00123 } 00124 // ----------------------------------------------------------------------------------- 00125 // size_t choose(const string& title, const string& answers, char separator) 00126 // ----------------------------------------------------------------------------------- 00127 size_t choose(const string& title, const string& answers, char separator) { 00128 vector<string> a; 00129 size_t start = 0; 00130 00131 while (1) { 00132 size_t sep = answers.find_first_of(separator, start); 00133 if (sep == string::npos) { 00134 a.push_back(answers.substr(start)); 00135 break; 00136 } 00137 a.push_back(answers.substr(start, sep-start)); 00138 start = sep+1; 00139 } 00140 return choose(title, a); 00141 } 00142 // ------------------------------------------- 00143 // void pause(const string& message) 00144 // ------------------------------------------- 00145 void pause(const string& message) { 00146 ask(message+" -- Press ENTER when ready", true); 00147 } 00148 }; 00149 }; 00150 00151 00152 00153 00154
Contact me in case of errors or questions. This documentation is powered by . |
(C) 2000-2002 |