From 07e0d37aba5cd72ff2d53eda654a4d5466e38627 Mon Sep 17 00:00:00 2001 From: Karen Arutyunov Date: Fri, 8 Nov 2019 00:17:47 +0300 Subject: Use path_name for `-` to stdin/stdout translation --- build2/b.cxx | 2 +- libbuild2/config/init.cxx | 12 +++++------- libbuild2/context.cxx | 2 +- libbuild2/dist/operation.cxx | 3 +-- libbuild2/file.cxx | 31 +++++++++++++++++-------------- libbuild2/file.hxx | 2 +- libbuild2/function.test.cxx | 2 +- libbuild2/lexer.hxx | 10 +++++----- libbuild2/lexer.test.cxx | 2 +- libbuild2/parser.cxx | 35 ++++++++++++++++++----------------- libbuild2/parser.hxx | 23 +++++++++++++---------- libbuild2/test/script/lexer.hxx | 2 +- libbuild2/test/script/lexer.test.cxx | 2 +- libbuild2/test/script/parser.cxx | 31 ++++++++++++++++++++----------- libbuild2/test/script/parser.hxx | 2 +- libbuild2/test/script/runner.cxx | 2 +- libbuild2/test/script/script.hxx | 4 ++-- libbuild2/token.hxx | 14 +++++++------- libbuild2/types.hxx | 7 ++++--- libbuild2/utility.cxx | 5 ++--- 20 files changed, 103 insertions(+), 90 deletions(-) diff --git a/build2/b.cxx b/build2/b.cxx index 1ebcc53..486b44c 100644 --- a/build2/b.cxx +++ b/build2/b.cxx @@ -605,7 +605,7 @@ main (int argc, char* argv[]) is.exceptions (istringstream::failbit | istringstream::badbit); parser p (*ctx); - bspec = p.parse_buildspec (is, path ("")); + bspec = p.parse_buildspec (is, path_name ("")); } catch (const io_error&) { diff --git a/libbuild2/config/init.cxx b/libbuild2/config/init.cxx index 890efa3..bcaea83 100644 --- a/libbuild2/config/init.cxx +++ b/libbuild2/config/init.cxx @@ -131,7 +131,7 @@ namespace build2 // never be init'ed). // auto load_config = [&rs, &c_v] (istream& is, - const path& f, + const path_name& in, const location& l) { // Check the config version. We assume that old versions cannot @@ -149,7 +149,7 @@ namespace build2 // that we won't have the config.version variable entered in the scope // but that is harmless (we could do it manually if necessary). // - lexer lex (is, f); + lexer lex (is, in); // Assume missing version is 0. // @@ -157,7 +157,7 @@ namespace build2 uint64_t v (p.second ? cast (p.first) : 0); if (v != module::version) - fail (l) << "incompatible config file " << f << + fail (l) << "incompatible config file " << in << info << "config file version " << v << (p.second ? "" : " (missing)") << info << "config module version " << module::version << @@ -169,11 +169,9 @@ namespace build2 auto load_config_file = [&load_config] (const path& f, const location& l) { - // @@ PATH_NAME TODO - // path_name fn (f); ifdstream ifs; - load_config (open_file_or_stdin (fn, ifs), f /* fn */, l); + load_config (open_file_or_stdin (fn, ifs), fn, l); }; { @@ -211,7 +209,7 @@ namespace build2 assert (false); #else istringstream is (host_config); - load_config (is, f, l); + load_config (is, path_name (s), l); #endif } else diff --git a/libbuild2/context.cxx b/libbuild2/context.cxx index 9ed69a5..b10aa3d 100644 --- a/libbuild2/context.cxx +++ b/libbuild2/context.cxx @@ -284,7 +284,7 @@ namespace build2 // (basically what's necessary inside a double-quoted literal plus the // single quote). // - path in (""); // @@ PATH_NAME: make name + path_name in (""); lexer l (is, in, 1 /* line */, "\'\"\\$("); // At the buildfile level the scope-specific variable should be diff --git a/libbuild2/dist/operation.cxx b/libbuild2/dist/operation.cxx index e3dadff..eb7cce1 100644 --- a/libbuild2/dist/operation.cxx +++ b/libbuild2/dist/operation.cxx @@ -144,8 +144,7 @@ namespace build2 // since the meta operation is dist and we know what we are doing. // values params; - const path locf (""); // @@ PATH_NAME TODO - const location loc (&locf); // Dummy location. + const location loc (path_name ("")); // Dummy location. const operations& ops (rs->root_extra->operations); diff --git a/libbuild2/file.cxx b/libbuild2/file.cxx index 2bc9af6..8d59d7c 100644 --- a/libbuild2/file.cxx +++ b/libbuild2/file.cxx @@ -163,25 +163,29 @@ namespace build2 { tracer trace ("source"); - const path& bf (l.name ()); + const path_name& fn (l.name ()); try { - l5 ([&]{trace << "sourcing " << bf;}); + l5 ([&]{trace << "sourcing " << fn;}); parser p (root.ctx, boot); p.parse_buildfile (l, root, base); } catch (const io_error& e) { - fail << "unable to read buildfile " << bf << ": " << e; + fail << "unable to read buildfile " << fn << ": " << e; } } static void - source (scope& root, scope& base, istream& is, const path& bf, bool boot) + source (scope& root, + scope& base, + istream& is, + const path_name& in, + bool boot) { - lexer l (is, bf); + lexer l (is, in); source (root, base, l, boot); } @@ -191,10 +195,8 @@ namespace build2 path_name fn (bf); try { - // @@ PATH_NAME TODO - // ifdstream ifs; - return source (root, base, open_file_or_stdin (fn, ifs), bf /* fn */, boot); + return source (root, base, open_file_or_stdin (fn, ifs), fn, boot); } catch (const io_error& e) { @@ -209,9 +211,9 @@ namespace build2 } void - source (scope& root, scope& base, istream& is, const path& bf) + source (scope& root, scope& base, istream& is, const path_name& in) { - source (root, base, is, bf, false); + source (root, base, is, in, false /* boot */); } void @@ -525,7 +527,7 @@ namespace build2 pair extract_variable (context& ctx, lexer& l, const variable& var) { - const path& bf (l.name ()); + const path_name& fn (l.name ()); try { @@ -553,7 +555,7 @@ namespace build2 } catch (const io_error& e) { - fail << "unable to read buildfile " << bf << ": " << e << endf; + fail << "unable to read buildfile " << fn << ": " << e << endf; } } @@ -563,7 +565,8 @@ namespace build2 const path& bf, const variable& var) { - lexer l (is, bf); + path_name in (bf); + lexer l (is, in); return extract_variable (ctx, l, var); } @@ -1665,7 +1668,7 @@ namespace build2 // name? // parser p (ctx); - names v (p.parse_export_stub (ifs, es, gs, ts)); + names v (p.parse_export_stub (ifs, path_name (es), gs, ts)); // If there were no export directive executed in an export stub, assume // the target is not exported. diff --git a/libbuild2/file.hxx b/libbuild2/file.hxx index 78bd049..ce57933 100644 --- a/libbuild2/file.hxx +++ b/libbuild2/file.hxx @@ -77,7 +77,7 @@ namespace build2 // diagnostics. // LIBBUILD2_SYMEXPORT void - source (scope& root, scope& base, istream&, const path& name); + source (scope& root, scope& base, istream&, const path_name&); // As above, but extract from a lexer (this could be useful for sourcing // stdin that requires parse_variable()). diff --git a/libbuild2/function.test.cxx b/libbuild2/function.test.cxx index 3cf2e7c..0fd16fd 100644 --- a/libbuild2/function.test.cxx +++ b/libbuild2/function.test.cxx @@ -125,7 +125,7 @@ namespace build2 scope& s (ctx.global_scope.rw ()); parser p (ctx); - p.parse_buildfile (cin, path ("buildfile"), s, s); + p.parse_buildfile (cin, path_name ("buildfile"), s, s); } catch (const failed&) { diff --git a/libbuild2/lexer.hxx b/libbuild2/lexer.hxx index bd2ac74..59debc4 100644 --- a/libbuild2/lexer.hxx +++ b/libbuild2/lexer.hxx @@ -88,12 +88,12 @@ namespace build2 // copied. // lexer (istream& is, - const path& name, + const path_name& name, uint64_t line = 1, // Start line in the stream. const char* escapes = nullptr) : lexer (is, name, line, escapes, true /* set_mode */) {} - const path& + const path_name& name () const {return name_;} // Note: sets mode for the next token. The second argument can be used to @@ -181,7 +181,7 @@ namespace build2 // Lexer state. // protected: - lexer (istream& is, const path& name, uint64_t line, + lexer (istream& is, const path_name& name, uint64_t line, const char* escapes, bool set_mode) : char_scanner (is, true /* crlf */, line), @@ -193,7 +193,7 @@ namespace build2 mode (lexer_mode::normal, '@', escapes); } - const path& name_; + const path_name& name_; std::stack state_; bool sep_; // True if we skipped spaces in peek(). @@ -210,7 +210,7 @@ namespace butl // ADL using namespace build2; assert (data != nullptr); // E.g., must be &lexer::name_. - return location (static_cast (data), c.line, c.column); + return location (*static_cast (data), c.line, c.column); } } diff --git a/libbuild2/lexer.test.cxx b/libbuild2/lexer.test.cxx index 2e2f152..32151db 100644 --- a/libbuild2/lexer.test.cxx +++ b/libbuild2/lexer.test.cxx @@ -48,7 +48,7 @@ namespace build2 // Most alternative modes auto-expire so we need something underneath. // - path in (""); // @@ PATH_NAME TODO + path_name in (""); lexer l (cin, in); if (m != lexer_mode::normal) diff --git a/libbuild2/parser.cxx b/libbuild2/parser.cxx index 7289338..9e586e0 100644 --- a/libbuild2/parser.cxx +++ b/libbuild2/parser.cxx @@ -211,9 +211,9 @@ namespace build2 }; void parser:: - parse_buildfile (istream& is, const path& p, scope& root, scope& base) + parse_buildfile (istream& is, const path_name& in, scope& root, scope& base) { - lexer l (is, p); + lexer l (is, in); parse_buildfile (l, root, base); } @@ -1315,20 +1315,20 @@ namespace build2 void parser:: source (istream& is, - const path& p, + const path_name& in, const location& loc, bool enter, bool deft) { tracer trace ("parser::source", &path_); - l5 ([&]{trace (loc) << "entering " << p;}); + l5 ([&]{trace (loc) << "entering " << in;}); if (enter) - enter_buildfile (p); + enter_buildfile (in); - const path* op (path_); - path_ = &p; + const path_name* op (path_); + path_ = ∈ lexer l (is, *path_); lexer* ol (lexer_); @@ -1358,7 +1358,7 @@ namespace build2 lexer_ = ol; path_ = op; - l5 ([&]{trace (loc) << "leaving " << p;}); + l5 ([&]{trace (loc) << "leaving " << in;}); } void parser:: @@ -1396,7 +1396,7 @@ namespace build2 { ifdstream ifs (p); source (ifs, - p, + path_name (p), get_location (t), true /* enter */, false /* default_target */); @@ -1537,7 +1537,7 @@ namespace build2 { ifdstream ifs (p); source (ifs, - p, + path_name (p), get_location (t), true /* enter */, true /* default_target */); @@ -1622,7 +1622,7 @@ namespace build2 }); source (is, - path (""), // @@ PATH_NAME TODO + path_name (""), l, false /* enter */, false /* default_target */); @@ -5382,9 +5382,9 @@ namespace build2 // normally: perform(update($identity(foo/ bar/))). // buildspec parser:: - parse_buildspec (istream& is, const path& name) // @@ PATH_NAME TODO + parse_buildspec (istream& is, const path_name& in) { - path_ = &name; + path_ = ∈ // We do "effective escaping" and only for ['"\$(] (basically what's // necessary inside a double-quoted literal plus the single quote). @@ -5809,11 +5809,12 @@ namespace build2 } void parser:: - enter_buildfile (const path& p) + enter_buildfile (const path_name& pn) { tracer trace ("parser::enter_buildfile", &path_); - dir_path d (p.directory ()); + const path& p (pn.path != nullptr ? *pn.path : path ()); + dir_path d (p.directory ()); // Empty for a path name with the NULL path. // Figure out if we need out. // @@ -5828,8 +5829,8 @@ namespace build2 ctx.targets.insert ( move (d), move (out), - p.leaf ().base ().string (), - p.extension (), // Always specified. + pn.name ? *pn.name : p.leaf ().base ().string (), + p.extension (), // Always specified. trace); } diff --git a/libbuild2/parser.hxx b/libbuild2/parser.hxx index 04a8e5c..d82496d 100644 --- a/libbuild2/parser.hxx +++ b/libbuild2/parser.hxx @@ -34,13 +34,16 @@ namespace build2 // Issue diagnostics and throw failed in case of an error. // void - parse_buildfile (istream&, const path& name, scope& root, scope& base); + parse_buildfile (istream&, + const path_name&, + scope& root, + scope& base); void parse_buildfile (lexer&, scope& root, scope& base); buildspec - parse_buildspec (istream&, const path& name); + parse_buildspec (istream&, const path_name&); token parse_variable (lexer&, scope&, const variable&, token_type kind); @@ -49,9 +52,9 @@ namespace build2 parse_variable_value (lexer&, scope&, const dir_path*, const variable&); names - parse_export_stub (istream& is, const path& p, scope& r, scope& b) + parse_export_stub (istream& is, const path_name& name, scope& r, scope& b) { - parse_buildfile (is, p, r, b); + parse_buildfile (is, name, r, b); return move (export_value_); } @@ -248,7 +251,7 @@ namespace build2 // void source (istream&, - const path&, + const path_name&, const location&, bool enter, bool default_target); @@ -467,7 +470,7 @@ namespace build2 // Enter buildfile as a target. // void - enter_buildfile (const path&); + enter_buildfile (const path_name&); // Lexer. // @@ -684,8 +687,8 @@ namespace build2 bool pre_parse_ = false; bool boot_; - const path* path_; // Current path. - lexer* lexer_; + const path_name* path_; // Current path name. + lexer* lexer_; prerequisite* prerequisite_ = nullptr; // Current prerequisite, if any. target* target_ = nullptr; // Current target, if any. @@ -704,8 +707,8 @@ namespace build2 enum class replay {stop, save, play} replay_ = replay::stop; replay_tokens replay_data_; - size_t replay_i_; // Position of the next token during replay. - const path* replay_path_; // Path before replay began (to be restored). + size_t replay_i_; // Position of the next token during replay. + const path_name* replay_path_; // Path before replay began (to be restored). }; } diff --git a/libbuild2/test/script/lexer.hxx b/libbuild2/test/script/lexer.hxx index 4083161..1b26224 100644 --- a/libbuild2/test/script/lexer.hxx +++ b/libbuild2/test/script/lexer.hxx @@ -48,7 +48,7 @@ namespace build2 // Note that neither the name nor escape arguments are copied. // lexer (istream& is, - const path& name, + const path_name& name, lexer_mode m, const char* escapes = nullptr) : base_lexer (is, name, 1 /* line */, diff --git a/libbuild2/test/script/lexer.test.cxx b/libbuild2/test/script/lexer.test.cxx index fc26acc..f6610e2 100644 --- a/libbuild2/test/script/lexer.test.cxx +++ b/libbuild2/test/script/lexer.test.cxx @@ -53,7 +53,7 @@ namespace build2 m == lexer_mode::description_line || m == lexer_mode::variable); - path in (""); // @@ PATH_NAME TODO + path_name in (""); lexer l (cin, in, u ? lexer_mode::command_line : m); if (u) l.mode (m); diff --git a/libbuild2/test/script/parser.cxx b/libbuild2/test/script/parser.cxx index d5e437b..376d68f 100644 --- a/libbuild2/test/script/parser.cxx +++ b/libbuild2/test/script/parser.cxx @@ -54,7 +54,8 @@ namespace build2 void parser:: pre_parse (istream& is, script& s) { - path_ = &*s.paths_.insert (s.script_target.path ()).first; + path_ = &*s.paths_.insert ( + path_name_value (s.script_target.path ())).first; pre_parse_ = true; @@ -78,7 +79,7 @@ namespace build2 // Start location of the implied script group is the beginning of // the file. End location -- end of the file. // - group_->start_loc_ = location (path_, 1, 1); + group_->start_loc_ = location (*path_, 1, 1); token t (pre_parse_scope_body ()); @@ -1007,29 +1008,37 @@ namespace build2 // It may be tempting to use relative paths in diagnostics but it // most likely will be misguided. // - auto enter_path = [this] (string n) -> const path& + auto enter_path = [this] (string n) -> const path_name_value& { path p (move (n)); if (p.relative ()) - p = path_->directory () / p; + { + // There is always the testscript path (path_ refers to an + // object in the script::paths_ set). + // + assert (path_->path != nullptr); + + p = path_->path->directory () / p; + } p.normalize (); - return *script_->paths_.insert (move (p)).first; + return *script_->paths_.insert (path_name_value (move (p))).first; }; - const path& p (enter_path (move (n))); + const path_name_value& pn (enter_path (move (n))); + const path& p (*pn.path); if (include_set_->insert (p).second || !once) { try { ifdstream ifs (p); - lexer l (ifs, p, lexer_mode::command_line); + lexer l (ifs, pn, lexer_mode::command_line); - const path* op (path_); - path_ = &p; + const path_name* op (path_); + path_ = &pn; lexer* ol (lexer_); set_lexer (&l); @@ -2303,7 +2312,7 @@ namespace build2 // istringstream is (s); - path in (""); // @@ PATH_NAME TODO + path_name in (""); lexer lex (is, in, lexer_mode::command_expansion, "\'\"\\"); @@ -3432,7 +3441,7 @@ namespace build2 value&& rhs, const string& attributes, token_type kind, - const path& name) + const path_name& name) { path_ = &name; diff --git a/libbuild2/test/script/parser.hxx b/libbuild2/test/script/parser.hxx index c8a1408..7dcd70d 100644 --- a/libbuild2/test/script/parser.hxx +++ b/libbuild2/test/script/parser.hxx @@ -48,7 +48,7 @@ namespace build2 value&& rhs, const string& attributes, token_type assign_kind, - const path& name); // For diagnostics. + const path_name&); // For diagnostics. // Recursive descent parser. // diff --git a/libbuild2/test/script/runner.cxx b/libbuild2/test/script/runner.cxx index e56dc41..181c5ce 100644 --- a/libbuild2/test/script/runner.cxx +++ b/libbuild2/test/script/runner.cxx @@ -1134,7 +1134,7 @@ namespace build2 value (move (ns)), *ats, token_type::assign, - path ("")); // @@ PATH_NAME TODO + path_name ("")); } } catch (const io_error& e) diff --git a/libbuild2/test/script/script.hxx b/libbuild2/test/script/script.hxx index 30bc6e8..f4ef32a 100644 --- a/libbuild2/test/script/script.hxx +++ b/libbuild2/test/script/script.hxx @@ -546,9 +546,9 @@ namespace build2 friend class parser; // Testscript file paths. Specifically, replay_token::file points to - // these paths. + // these path names. // - std::set paths_; + std::set paths_; }; } } diff --git a/libbuild2/token.hxx b/libbuild2/token.hxx index 0ee5248..2370f8d 100644 --- a/libbuild2/token.hxx +++ b/libbuild2/token.hxx @@ -161,32 +161,32 @@ namespace build2 struct replay_token { build2::token token; - const path* file; + const path_name* file; lexer_mode_base mode; using location_type = build2::location; location_type - location () const {return location_type (file, token.line, token.column);} + location () const {return location_type (*file, token.line, token.column);} }; using replay_tokens = vector; // Diagnostics plumbing. We assume that any diag stream for which we can use - // token as location has its aux data pointing to pointer to path. + // token as location has its aux data pointing to pointer to path name. // inline location - get_location (const token& t, const path& p) + get_location (const token& t, const path_name& pn) { - return location (&p, t.line, t.column); + return location (pn, t.line, t.column); } inline location get_location (const token& t, const void* data) { assert (data != nullptr); // E.g., must be &parser::path_. - const path* p (*static_cast (data)); - return get_location (t, *p); + const path_name* pn (*static_cast (data)); + return get_location (t, *pn); } } diff --git a/libbuild2/types.hxx b/libbuild2/types.hxx index 192b01f..bedcf1a 100644 --- a/libbuild2/types.hxx +++ b/libbuild2/types.hxx @@ -228,6 +228,7 @@ namespace build2 // using butl::path; using butl::path_name; + using butl::path_name_value; using butl::dir_path; using butl::path_cast; using butl::basic_path; @@ -321,11 +322,11 @@ namespace build2 : file (f), line (l), column (c) {} explicit - location (const path_name& f, uint64_t l = 0, uint64_t c = 0) - : file (f), line (l), column (c) {} + location (path_name f, uint64_t l = 0, uint64_t c = 0) + : file (std::move (f)), line (l), column (c) {} bool - empty () const {return file.path == nullptr;} + empty () const {return file.empty ();} path_name file; uint64_t line; diff --git a/libbuild2/utility.cxx b/libbuild2/utility.cxx index b7637f5..528b435 100644 --- a/libbuild2/utility.cxx +++ b/libbuild2/utility.cxx @@ -47,6 +47,8 @@ namespace std ostream& operator<< (ostream& os, const ::butl::path_name& pn) { + assert (!pn.empty ()); + return pn.name ? (os << *pn.name) : (os << *pn.path); } @@ -117,9 +119,6 @@ namespace build2 string diag_relative (const path& p, bool cur) { - if (p.string () == "-") // @@ PATH_NAME: remove - return ""; - const path& b (*relative_base); if (p.absolute ()) -- cgit v1.1