summaryrefslogtreecommitdiff
path: root/cli
diff options
context:
space:
mode:
authorKaren Arutyunov <karen@codesynthesis.com>2020-03-25 21:38:42 +0300
committerKaren Arutyunov <karen@codesynthesis.com>2020-03-27 16:37:56 +0300
commit1eeae97a9c650421d056a8c249c29fe42244ccd8 (patch)
tree7d53c75be685152a594485cf1eae9f5caa091574 /cli
parentcf89cd04b3cd95667e6d6d5d3821d191dc62b759 (diff)
Add peek_file() and peek_line() functions to argv_file_scanner
Diffstat (limited to 'cli')
-rw-r--r--cli/runtime-header.cxx26
-rw-r--r--cli/runtime-source.cxx36
2 files changed, 55 insertions, 7 deletions
diff --git a/cli/runtime-header.cxx b/cli/runtime-header.cxx
index 3a51b20..adf70dd 100644
--- a/cli/runtime-header.cxx
+++ b/cli/runtime-header.cxx
@@ -12,7 +12,8 @@ generate_runtime_header (context& ctx)
ostream& os (ctx.os);
if (ctx.options.generate_file_scanner ())
- os << "#include <deque>" << endl;
+ os << "#include <list>" << endl
+ << "#include <deque>" << endl;
if (ctx.options.generate_description ())
os << "#include <map>" << endl;
@@ -456,6 +457,19 @@ generate_runtime_header (context& ctx)
<< "virtual void" << endl
<< "skip ();"
<< endl
+ << "// Return the file path if the peeked at argument came from a file and" << endl
+ << "// the empty string otherwise. The reference is guaranteed to be valid" << endl
+ << "// till the end of the scanner lifetime." << endl
+ << "//" << endl
+ << "const std::string&" << endl
+ << "peek_file ();"
+ << endl
+ << "// Return the 1-based line number if the peeked at argument came from" << endl
+ << "// a file and zero otherwise." << endl
+ << "//" << endl
+ << "std::size_t" << endl
+ << "peek_line ();"
+ << endl
<< "private:" << endl
<< "const option_info*" << endl
<< "find (const char*) const;"
@@ -470,7 +484,14 @@ generate_runtime_header (context& ctx)
<< "const option_info* options_;"
<< "std::size_t options_count_;"
<< endl
- << "std::deque<std::string> args_;"
+ << "struct arg"
+ << "{"
+ << "std::string value;"
+ << "const std::string* file;"
+ << "std::size_t line;"
+ << "};"
+ << "std::deque<arg> args_;"
+ << "std::list<std::string> files_;"
<< endl
<< "// Circular buffer of two arguments." << endl
<< "//" << endl
@@ -483,6 +504,7 @@ generate_runtime_header (context& ctx)
os << endl
<< "static int zero_argc_;"
+ << "static std::string empty_string_;"
<< "};";
}
diff --git a/cli/runtime-source.cxx b/cli/runtime-source.cxx
index b836406..36d8968 100644
--- a/cli/runtime-source.cxx
+++ b/cli/runtime-source.cxx
@@ -365,6 +365,7 @@ generate_runtime_source (context& ctx, bool complete)
<< "//" << endl
<< "int argv_file_scanner::zero_argc_ = 0;"
+ << "std::string argv_file_scanner::empty_string_;"
<< endl
<< "bool argv_file_scanner::" << endl
@@ -452,7 +453,25 @@ generate_runtime_source (context& ctx, bool complete)
<< "if (!more ())" << endl
<< "throw eos_reached ();"
<< endl
- << "return args_.empty () ? base::peek () : args_.front ().c_str ();"
+ << "return args_.empty () ? base::peek () : args_.front ().value.c_str ();"
+ << "}"
+
+ << "const std::string& argv_file_scanner::" << endl
+ << "peek_file ()"
+ << "{"
+ << "if (!more ())" << endl
+ << "throw eos_reached ();"
+ << endl
+ << "return args_.empty () ? empty_string_ : *args_.front ().file;"
+ << "}"
+
+ << "std::size_t argv_file_scanner::" << endl
+ << "peek_line ()"
+ << "{"
+ << "if (!more ())" << endl
+ << "throw eos_reached ();"
+ << endl
+ << "return args_.empty () ? 0 : args_.front ().line;"
<< "}"
<< "const char* argv_file_scanner::" << endl
@@ -465,7 +484,7 @@ generate_runtime_source (context& ctx, bool complete)
<< "return base::next ();"
<< "else"
<< "{"
- << "hold_[i_ == 0 ? ++i_ : --i_].swap (args_.front ());"
+ << "hold_[i_ == 0 ? ++i_ : --i_].swap (args_.front ().value);"
<< "args_.pop_front ();"
<< "return hold_[i_].c_str ();"
<< "}"
@@ -503,7 +522,12 @@ generate_runtime_source (context& ctx, bool complete)
<< "if (!is.is_open ())" << endl
<< "throw file_io_failure (file);"
<< endl
- << "while (!is.eof ())"
+ << "files_.push_back (file);"
+ << endl
+ << "arg a;"
+ << "a.file = &*files_.rbegin ();"
+ << endl
+ << "for (a.line = 1; !is.eof (); ++a.line)"
<< "{"
<< "string line;"
<< "getline (is, line);"
@@ -633,9 +657,11 @@ generate_runtime_source (context& ctx, bool complete)
<< endl
<< "continue;"
<< "}"
- << "args_.push_back (s1);"
+ << "a.value = s1;"
+ << "args_.push_back (a);"
<< "}"
- << "args_.push_back (s2);"
+ << "a.value = s2;"
+ << "args_.push_back (a);"
<< "}" // while
<< "}";
}