summaryrefslogtreecommitdiffstats
path: root/cli
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2011-01-20 15:38:10 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2011-01-20 15:38:10 +0200
commit0267ede2d356abdef7b3e9af19d4725605a58947 (patch)
tree169a57693ec56a1273f2556d311d8df0d5b72974 /cli
parent50a1ae06f83a353a3b9ff7d473122e60ad5f5636 (diff)
downloadcli-0267ede2d356abdef7b3e9af19d4725605a58947.tar.gz
cli-0267ede2d356abdef7b3e9af19d4725605a58947.tar.xz
cli-0267ede2d356abdef7b3e9af19d4725605a58947.zip
Add support for multiple file options and file search callbacks
Diffstat (limited to 'cli')
-rw-r--r--cli/runtime-header.cxx33
-rw-r--r--cli/runtime-inline.cxx43
-rw-r--r--cli/runtime-source.cxx35
3 files changed, 100 insertions, 11 deletions
diff --git a/cli/runtime-header.cxx b/cli/runtime-header.cxx
index 1e4941b..41c56c9 100644
--- a/cli/runtime-header.cxx
+++ b/cli/runtime-header.cxx
@@ -21,6 +21,7 @@ generate_runtime_header (context& ctx)
os << "#include <iosfwd>" << endl
<< "#include <string>" << endl
+ << "#include <cstddef>" << endl
<< "#include <exception>" << endl
<< endl;
@@ -266,13 +267,32 @@ generate_runtime_header (context& ctx)
<< "public:" << endl
<< "argv_file_scanner (int& argc," << endl
<< "char** argv," << endl
- << "const std::string& file_option," << endl
+ << "const std::string& option," << endl
<< "bool erase = false);"
<< endl
<< "argv_file_scanner (int start," << endl
<< "int& argc," << endl
<< "char** argv," << endl
- << "const std::string& file_option," << endl
+ << "const std::string& option," << endl
+ << "bool erase = false);"
+ << endl
+ << "struct option_info"
+ << "{"
+ << " const char* option;"
+ << " std::string (*search_func) (const char*, void* arg);"
+ << " void* arg;"
+ << "};"
+ << "argv_file_scanner (int& argc," << endl
+ << "char** argv," << endl
+ << "const option_info* options," << endl
+ << "std::size_t options_count," << endl
+ << "bool erase = false);"
+ << endl
+ << "argv_file_scanner (int start," << endl
+ << "int& argc," << endl
+ << "char** argv," << endl
+ << "const option_info* options," << endl
+ << "std::size_t options_count," << endl
<< "bool erase = false);"
<< endl
<< "virtual bool" << endl
@@ -288,12 +308,19 @@ generate_runtime_header (context& ctx)
<< "skip ();"
<< endl
<< "private:" << endl
+ << "const option_info*" << endl
+ << "find (const char*) const;"
+ << endl
<< "void" << endl
- << "load (const char* file);"
+ << "load (const std::string& file);"
<< endl
<< "typedef argv_scanner base;"
<< endl
<< "const std::string option_;"
+ << "option_info option_info_;"
+ << "const option_info* options_;"
+ << "std::size_t options_count_;"
+ << endl
<< "std::string hold_;"
<< "std::deque<std::string> args_;";
diff --git a/cli/runtime-inline.cxx b/cli/runtime-inline.cxx
index 633d7db..4d95a78 100644
--- a/cli/runtime-inline.cxx
+++ b/cli/runtime-inline.cxx
@@ -189,11 +189,15 @@ generate_runtime_inline (context& ctx)
<< "const std::string& option," << endl
<< "bool erase)" << endl
<< ": argv_scanner (argc, argv, erase)," << endl
- << " option_ (option)";
+ << " option_ (option)," << endl
+ << " options_ (&option_info_)," << endl
+ << " options_count_ (1)";
if (sep)
os << "," << endl
<< " skip_ (false)";
os << "{"
+ << "option_info_.option = option_.c_str ();"
+ << "option_info_.search_func = 0;"
<< "}";
os << inl << "argv_file_scanner::" << endl
@@ -203,7 +207,42 @@ generate_runtime_inline (context& ctx)
<< "const std::string& option," << endl
<< "bool erase)" << endl
<< ": argv_scanner (start, argc, argv, erase)," << endl
- << " option_ (option)";
+ << " option_ (option)," << endl
+ << " options_ (&option_info_)," << endl
+ << " options_count_ (1)";
+ if (sep)
+ os << "," << endl
+ << " skip_ (false)";
+ os << "{"
+ << "option_info_.option = option_.c_str ();"
+ << "option_info_.search_func = 0;"
+ << "}";
+
+ os << inl << "argv_file_scanner::" << endl
+ << "argv_file_scanner (int& argc," << endl
+ << "char** argv," << endl
+ << "const option_info* options," << endl
+ << "std::size_t options_count," << endl
+ << "bool erase)" << endl
+ << ": argv_scanner (argc, argv, erase)," << endl
+ << " options_ (options)," << endl
+ << " options_count_ (options_count)";
+ if (sep)
+ os << "," << endl
+ << " skip_ (false)";
+ os << "{"
+ << "}";
+
+ os << inl << "argv_file_scanner::" << endl
+ << "argv_file_scanner (int start," << endl
+ << "int& argc," << endl
+ << "char** argv," << endl
+ << "const option_info* options," << endl
+ << "std::size_t options_count," << endl
+ << "bool erase)" << endl
+ << ": argv_scanner (start, argc, argv, erase)," << endl
+ << " options_ (options)," << endl
+ << " options_count_ (options_count)";
if (sep)
os << "," << endl
<< " skip_ (false)";
diff --git a/cli/runtime-source.cxx b/cli/runtime-source.cxx
index cae8c84..4c6b2a2 100644
--- a/cli/runtime-source.cxx
+++ b/cli/runtime-source.cxx
@@ -255,14 +255,18 @@ generate_runtime_source (context& ctx)
<< "// See if the next argument is the file option." << endl
<< "//" << endl
<< "const char* a (base::peek ());"
+ << "const option_info* oi;"
<< endl
- << "if (" << (sep ? "!skip_ && " : "") << "a == option_)"
+ << "if (" << (sep ? "!skip_ && " : "") << "(oi = find (a)))"
<< "{"
<< "base::next ();"
<< endl
<< "if (!base::more ())" << endl
- << "throw missing_value (option_);"
+ << "throw missing_value (oi->option);"
<< endl
+ << "if (oi->search_func != 0)" << endl
+ << "load (oi->search_func (base::next (), oi->arg));"
+ << "else" << endl
<< "load (base::next ());"
<< endl
<< "if (!args_.empty ())" << endl
@@ -317,12 +321,22 @@ generate_runtime_source (context& ctx)
<< "args_.pop_front ();"
<< "}"
+ << "const argv_file_scanner::option_info* argv_file_scanner::" << endl
+ << "find (const char* a) const"
+ << "{"
+ << "for (std::size_t i (0); i < options_count_; ++i)" << endl
+ << "if (std::strcmp (a, options_[i].option) == 0)" << endl
+ << "return &options_[i];"
+ << endl
+ << "return 0;"
+ << "}"
+
<< "void argv_file_scanner::" << endl
- << "load (const char* file)"
+ << "load (const std::string& file)"
<< "{"
<< "using namespace std;"
<< endl
- << "ifstream is (file);"
+ << "ifstream is (file.c_str ());"
<< endl
<< "if (!is.is_open ())" << endl
<< "throw file_io_failure (file);"
@@ -400,8 +414,17 @@ generate_runtime_source (context& ctx)
<< endl
<< "s2 = string (s2, 1, n - 2);"
<< "}"
- << "if (" << (sep ? "!skip_ && " : "") << "s1 == option_)" << endl
- << "load (s2.c_str ());"
+ << "const option_info* oi;"
+ << "if (" << (sep ? "!skip_ && " : "") << "(oi = find (s1.c_str ())))" << endl
+ << "{"
+ << "if (s2.empty ())" << endl
+ << "throw missing_value (oi->option);"
+ << endl
+ << "if (oi->search_func != 0)" << endl
+ << "load (oi->search_func (s2.c_str (), oi->arg));"
+ << "else" << endl
+ << "load (s2);"
+ << "}"
<< "else"
<< "{"
<< "args_.push_back (s1);"