diff options
Diffstat (limited to 'cli/cli/runtime-source.cxx')
-rw-r--r-- | cli/cli/runtime-source.cxx | 75 |
1 files changed, 71 insertions, 4 deletions
diff --git a/cli/cli/runtime-source.cxx b/cli/cli/runtime-source.cxx index 3864163..81eab4a 100644 --- a/cli/cli/runtime-source.cxx +++ b/cli/cli/runtime-source.cxx @@ -15,6 +15,7 @@ generate_runtime_source (context& ctx, bool complete) << "#include <set>" << endl << "#include <string>" << endl << "#include <vector>" << endl + << "#include <utility>" << endl // pair << "#include <ostream>" << endl << "#include <sstream>" << endl; @@ -259,6 +260,10 @@ generate_runtime_source (context& ctx, bool complete) // argv_scanner // + // Note that due to the erase logic we cannot just add i_ to + // start_position and so have to increment it instead. See also + // argv_file_scanner that continues with this logic. + // os << "// argv_scanner" << endl << "//" << endl @@ -295,6 +300,7 @@ generate_runtime_source (context& ctx, bool complete) << "else" << endl << "++i_;" << endl + << "++start_position_;" << "return r;" << "}" << "else" << endl @@ -304,10 +310,19 @@ generate_runtime_source (context& ctx, bool complete) << "void argv_scanner::" << endl << "skip ()" << "{" - << "if (i_ < argc_)" << endl + << "if (i_ < argc_)" + << "{" << "++i_;" + << "++start_position_;" + << "}" << "else" << endl << "throw eos_reached ();" + << "}" + + << "std::size_t argv_scanner::" << endl + << "position ()" + << "{" + << "return start_position_;" << "}"; // vector_scanner @@ -348,11 +363,19 @@ generate_runtime_source (context& ctx, bool complete) << "++i_;" << "else" << endl << "throw eos_reached ();" + << "}" + + << "std::size_t vector_scanner::" << endl + << "position ()" + << "{" + << "return start_position_ + i_;" << "}"; } // argv_file_scanner // + // Note that we continue incrementing start_position like argv_scanner. + // if (ctx.options.generate_file_scanner ()) { bool sep (!ctx.opt_sep.empty ()); @@ -486,6 +509,7 @@ generate_runtime_source (context& ctx, bool complete) << "{" << "hold_[i_ == 0 ? ++i_ : --i_].swap (args_.front ().value);" << "args_.pop_front ();" + << "++start_position_;" << "return hold_[i_].c_str ();" << "}" << "}" @@ -498,8 +522,11 @@ generate_runtime_source (context& ctx, bool complete) << endl << "if (args_.empty ())" << endl << "return base::skip ();" - << "else" << endl + << "else" + << "{" << "args_.pop_front ();" + << "++start_position_;" + << "}" << "}" << "const argv_file_scanner::option_info* argv_file_scanner::" << endl @@ -512,6 +539,12 @@ generate_runtime_source (context& ctx, bool complete) << "return 0;" << "}" + << "std::size_t argv_file_scanner::" << endl + << "position ()" + << "{" + << "return start_position_;" + << "}" + << "void argv_file_scanner::" << endl << "load (const std::string& file)" << "{" @@ -734,6 +767,12 @@ generate_runtime_source (context& ctx, bool complete) << "scan_group (skipped);" << "}" + << "std::size_t group_scanner::" << endl + << "position ()" + << "{" + << "return scan_.position ();" + << "}" + << "void group_scanner::" << endl << "scan_group (state st)" << "{" @@ -746,6 +785,11 @@ generate_runtime_source (context& ctx, bool complete) << "throw unexpected_group (arg_[i_], group_scan_.next ());" << "}" + // Note that while it may seem like a good idea to pass + // scan_.position() to reset() below, the trailing group positions + // will overlap with the argument's. So it seems best to start + // positions of each argument in a group from 0. + // << "if (state_ != peeked)" << "{" << "arg_[i_ == 0 ? ++i_ : --i_].clear ();" @@ -934,6 +978,28 @@ generate_runtime_source (context& ctx, bool complete) os << "};"; + // parser<std::pair<X, std::size_t>> + // + os << "template <typename X>" << endl + << "struct parser<std::pair<X, std::size_t> >" + << "{"; + + os << "static void" << endl + << "parse (std::pair<X, std::size_t>& x, " << (sp ? "bool& xs, " : "") << "scanner& s)" + << "{" + << "x.second = s.position ();" + << "parser<X>::parse (x.first, " << (sp ? "xs, " : "") << "s);" + << "}"; + + if (gen_merge) + os << "static void" << endl + << "merge (std::pair<X, std::size_t>& b, const std::pair<X, std::size_t>& a)" + << "{" + << "b = a;" + << "}"; + + os << "};"; + // parser<std::vector<X>> // os << "template <typename X>" << endl @@ -1001,6 +1067,7 @@ generate_runtime_source (context& ctx, bool complete) << endl << "if (s.more ())" << "{" + << "std::size_t pos (s.position ());" << "std::string ov (s.next ());" << "std::string::size_type p = ov.find ('=');" << endl @@ -1020,13 +1087,13 @@ generate_runtime_source (context& ctx, bool complete) os << "if (!kstr.empty ())" << "{" << "av[1] = const_cast<char*> (kstr.c_str ());" - << "argv_scanner s (0, ac, av);" + << "argv_scanner s (0, ac, av, false, pos);" << "parser<K>::parse (k, " << (sp ? "dummy, " : "") << "s);" << "}" << "if (!vstr.empty ())" << "{" << "av[1] = const_cast<char*> (vstr.c_str ());" - << "argv_scanner s (0, ac, av);" + << "argv_scanner s (0, ac, av, false, pos);" << "parser<V>::parse (v, " << (sp ? "dummy, " : "") << "s);" << "}" << "m[k] = v;" |