diff --git a/pub/src/axis.h b/pub/src/axis.h index 70f07bcc97adda2953734e25807e2f37b0729209..b3b608ace0bb353109980f2cb6d29cec39bb4a94 100644 --- a/pub/src/axis.h +++ b/pub/src/axis.h @@ -7,7 +7,6 @@ class CAxis { CAxis( bool _log ) : logflag(_log), force(false) { setAuto(); }; - void Ask( string quest ); void setLog( bool _log ); void setAuto(); diff --git a/pub/src/coord.cpp b/pub/src/coord.cpp index 6d8df4a56cf6704838cf3d1d9d9f8e8da72d9bf7..4696b205e2025e268bc14e201b9a8dffa3e4154d 100644 --- a/pub/src/coord.cpp +++ b/pub/src/coord.cpp @@ -8,8 +8,10 @@ #include <math.h> #include <stdlib.h> #include <string.h> +#include <iostream> -#include <ask_and_callback.h> +#include <ask_simple_value.h> // for ASK flags +#include <readln.h> using namespace std; @@ -20,52 +22,69 @@ using namespace std; // class CCoord // //**************************************************************************// -char CoordDecode( const string& resp, CCoord *rval ) +CCoord CCoord::Ask( const string& quest, const int flags, const CCoord& defval ) { - if (resp[0]=='\0') { - return 'd'; - } else if ( resp=="?" ) { - return 'h'; - } else if ( resp=="\\EOL" ) { - *rval = CCoord(); - return 'v'; - } - - uint i, j, np, n; - n = resp.size(); - if (resp[n-1]!=')') { - return 'h'; - } - for(j=n-2, np=1; j!=(uint)-1; j--) { - if (resp[j]==')') - np++; - else if (resp[j]=='(') { - np--; - if (np==0) break; + string defstr(""); + if( flags & ASK_DEF_GIVEN ) + defstr = defval.str(); + + string prompt = quest; + if ( defstr!="" && !(flags & ASK_DEF_NOT_SHOW) ) + prompt += " [" + defstr + "] ?"; + prompt += " "; + + for( ;; ) { + string resp = NRead::readln(prompt); + if ( resp == "\\q" ) { + throw "user escape to main menu"; + } else if ( resp == "" ) { + if ( defstr!="" ) + return defval; + cout << "no default available\n"; + } else if ( resp == "?" ) { + cout << "required input type: coordinate name and unit\n"; + cout << "input must be in the form: name (unit)\n"; + if( defstr!="" ) + cout << "just press ENTER to accept default [" << + defstr << "]\n"; + } else { + uint i, j, np, n; + n = resp.size(); + if (resp[n-1]!=')') { + cout << "input must terminate with ')'\n"; + continue; + } + for(j=n-2, np=1; j!=(uint)-1; j--) { + if (resp[j]==')') + np++; + else if (resp[j]=='(') { + np--; + if (np==0) break; + } + } + if (np!=0){ + cout << "input must contain balanced parentheses\n"; + continue; + } + for (i=j; i>0 && strchr(" \t",resp[i-1]); i--) ; + if (i==0){ + cout << "input must contain a non-empty coordinate name\n"; + continue; + } + return CCoord( resp.substr(0,i), resp.substr(j+1, n-j-2) ); } } - if (np!=0) return 'h'; - - for (i=j; i>0 && strchr(" \t",resp[i-1]); i--) ; - if (i==0) return 'h'; - - *rval = CCoord( resp.substr(0,i), resp.substr(j+1, n-j-2) ); - return 'v'; + } -const char* CCoord::helptext = -"a coordinate: <name> (<unit>)"; - CCoord CCoord::Ask( const string& quest, const CCoord& defval ) { - *this = myask( quest, 1, defval, defval.str(), helptext, CoordDecode ); - return *this; + return Ask( quest, 1, defval ); } CCoord CCoord::Ask( const string& quest ) { - *this = myask( quest, 0, CCoord(), "", helptext, CoordDecode ); - return *this; + return Ask( quest, 0, CCoord() ); } string CCoord::str( int maxlen ) const diff --git a/pub/src/coord.h b/pub/src/coord.h index 942bab78c3f279cdf74fd7a3b2894cfdda91f5f2..24cfdb2eb4be3dcc414968dbaaf2f5020aa40e23 100644 --- a/pub/src/coord.h +++ b/pub/src/coord.h @@ -6,6 +6,7 @@ class CCoord { CCoord( const string _name, const string _unit) : name(_name), unit(_unit) {}; + CCoord Ask( const string& quest, const int flags, const CCoord& defval ); CCoord Ask( const string& quest, const CCoord& defval ); CCoord Ask( const string& quest ); diff --git a/pub/src/index.cpp b/pub/src/index.cpp index 23e3ebd032c975ef91238437527c75357d4a638f..3d3f274a280356e3ec6619c7cdc6b5d8ab262589 100644 --- a/pub/src/index.cpp +++ b/pub/src/index.cpp @@ -10,7 +10,8 @@ #include <iostream> #include <algorithm> -#include <ask_and_callback.h> +#include <ask_simple_value.h> // for ASK flags +#include <readln.h> using namespace std; @@ -86,11 +87,11 @@ void IndexSet::parse(const string s, const uint v0, const uint vn) IndexParse::ParseSet(&T, s, v0, vn); } -void IndexSet::ask(const string quest, const string def, - const uint v0, const uint vn) +void IndexSet::ask( const string& quest, const string& def, + const uint v0, const uint vn ) { - string ans = index_ask(quest, def, v0, vn); - parse(ans, v0, vn); + string resp = index_ask(quest, def, v0, vn); + parse( resp, v0, vn ); } // *** info *** @@ -237,37 +238,40 @@ void IndexParse::ParseValue(string inp, int which, uint *val) strg(p0) + ".." + strg(pn); } -// *** user interaction *** -const char * IndexDialog::helptext = - "a list (a set of indices):\n" - " list: <empty_list> | <finite_list> | <infinite_list>\n" - " empty_list: -\n" - " finite_list: <range_with_skip> { , <range_with_skip> }\n" - " infinite_list: *\n" - " range_with_skip: <range> [ . <skip> ]\n" - " range: <bound> [ - <bound>]\n" - " skip: (integer >= 1)\n" - " bound: * | (integer >= 0)\n"; +// just get a string; do not parse nor check for validity. -char IndexDialog::decode(const string& resp, string *rval ) +string index_ask( const string& quest, const string& defstr, uint p0, uint pn ) { - if ( resp=="" ) { - return 'd'; - } else if ( resp=="?" ) { - return 'h'; + string prompt = quest; + if ( defstr!="" ) + prompt += " [" + defstr + "] ?"; + prompt += " "; + + for( ;; ) { + string resp = NRead::readwd(prompt); + if ( resp == "\\q" ) { + throw "user escape to main menu"; + } else if ( resp == "" ) { + if ( defstr!="" ) + return defstr; + else + cout << "empty input not allowed; " << + "use '-' for empty list, '?' for help\n"; + } else if ( resp == "?" ) { + cout << "required input type: index list (without blanks)\n" + "examples:\n" + " 0,2,7 comma-separated list of values\n" + " 0-7 range\n" + " 0-7.2 each 2nd: 0,2,4,6\n" + " - empty list\n" + " * full range, according to context\n" + " 8-* from 8 to end of range\n"; + if( defstr!="" ) + cout << "just press ENTER to accept default [" << + defstr << "]\n"; + } else { + return resp; + } } - *rval = resp; - // IndexParse::ParseTest( *rval, 0, 0 ); - return 'v'; -} - -string index_ask( const string& quest, string def, uint p0, uint pn ) -{ - uint lims[2]; - lims[0] = p0; - lims[1] = pn; - int defflag = ASK_DEF_GIVEN*(def!="") | ASK_WORD; - return myask( quest, defflag, def, def, - IndexDialog::helptext, IndexDialog::decode ); } diff --git a/pub/src/index.h b/pub/src/index.h index 133c6aeb1803b007bf95337215dd774439006c9f..dd43e8ba0500b93139ff3665eecc641281433bfc 100644 --- a/pub/src/index.h +++ b/pub/src/index.h @@ -25,11 +25,11 @@ public: // from text (returns 0 if string is valid): void parse( const string s, const uint v0=0, const uint vn=0 ); - void ask( const string quest, const string def, + void ask( const string& quest, const string& defstr, const uint v0=0, const uint vn=0 ); - void ask( const string quest, const IndexSet set, + void ask( const string& quest, const IndexSet set, const uint v0=0, const uint vn=0 ) { - ask(quest, set.str(), v0, vn); }; + ask( quest, set.str(), v0, vn ); }; // Info: uint size() const { return T.size(); }; @@ -39,6 +39,7 @@ public: const char* c_str() const { return str().c_str(); } ; }; + class IndexSetIterator : private IndexSet { private: set<uint>::iterator pos; @@ -77,4 +78,5 @@ public: }; -string index_ask(const string& quest, string def="", uint p0=0, uint pn=0); +string index_ask( const string& quest, const string& def="", + uint p0=0, uint pn=0); diff --git a/pub/src/manip.cpp b/pub/src/manip.cpp index f76f796d0444ed0e6dac1bd5db0c13001b8a9413..8afd9c5dc3f611fac2c71015826cf15980af9a2b 100644 --- a/pub/src/manip.cpp +++ b/pub/src/manip.cpp @@ -111,7 +111,7 @@ void NManip::PtsAvge() NOlm::SelAssert(); static string groups; - groups = index_ask("Start bins at points", groups); + groups = index_ask( "Start bins at points", groups ); if (groups=="") return; NOlm::IterateD fiter;