From a82cdb8fd9ba02034d296769772cdf81244da66a Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Mon, 20 Apr 2015 13:01:46 +0200 Subject: Automatically decide when to print relative/absolute paths --- build/buildfile | 4 +-- build/config/operation.cxx | 12 +++------ build/context.cxx | 16 +++-------- build/context.txx | 25 +++++++++-------- build/cxx/module.cxx | 2 +- build/cxx/rule.cxx | 6 ++--- build/diagnostics | 67 +++++++++++++++++++++++++++++++++++++--------- build/diagnostics.cxx | 11 ++++++-- build/dump.cxx | 2 +- build/parser.cxx | 2 +- build/path-io | 23 ++++------------ build/path-io.cxx | 38 ++++++++++++++++++++++++++ build/rule.cxx | 7 +++-- 13 files changed, 135 insertions(+), 80 deletions(-) create mode 100644 build/path-io.cxx diff --git a/build/buildfile b/build/buildfile index 35b4434..b3dfb4a 100644 --- a/build/buildfile +++ b/build/buildfile @@ -2,8 +2,8 @@ cxx = cxx/{target rule module} config = config/{operation module} exe{b b-prev}: cxx{b algorithm name operation spec scope variable target \ - prerequisite rule file module native context search diagnostics \ - token lexer parser process timestamp path utility filesystem dump \ + prerequisite rule file module native context search diagnostics token \ + lexer parser process timestamp path path-io utility filesystem dump \ options $config $cxx} .: exe{b b-prev} diff --git a/build/config/operation.cxx b/build/config/operation.cxx index ec9e4e6..3e4d64a 100644 --- a/build/config/operation.cxx +++ b/build/config/operation.cxx @@ -40,10 +40,7 @@ namespace build { path f (out_root / src_root_file); - if (verb >= 1) - text << "config::save_src_root " << f.string (); - else - text << "save " << f; + text << (verb ? "config::save_src_root " : "save ") << f; try { @@ -71,10 +68,7 @@ namespace build const dir_path& out_root (root.path ()); path f (out_root / config_file); - if (verb >= 1) - text << "config::save_config " << f.string (); - else - text << "save " << f; + text << (verb ? "config::save_config " : "save ") << f; try { @@ -322,7 +316,7 @@ namespace build { case rmdir_status::not_empty: { - warn << "directory " << out_root.string () << " is " + warn << "directory " << out_root << " is " << (out_root == work ? "current working directory" : "not empty") << ", not removing"; diff --git a/build/context.cxx b/build/context.cxx index 958fb98..1bd5033 100644 --- a/build/context.cxx +++ b/build/context.cxx @@ -58,22 +58,12 @@ namespace build } catch (const system_error& e) { - if (verb >= 1) - text << "mkdir " << d.string (); - else - text << "mkdir " << d; - - fail << "unable to create directory " << d.string () << ": " - << e.what (); + text << "mkdir " << d; + fail << "unable to create directory " << d << ": " << e.what (); } if (ms == mkdir_status::success) - { - if (verb >= 1) - text << "mkdir " << d.string (); - else - text << "mkdir " << d; - } + text << "mkdir " << d; return ms; } diff --git a/build/context.txx b/build/context.txx index 218c65e..5c93221 100644 --- a/build/context.txx +++ b/build/context.txx @@ -25,18 +25,18 @@ namespace build } catch (const std::system_error& e) { - if (verb >= 1) - text << "rm " << f.string (); + if (verb) + text << "rm " << f; else text << "rm " << t; - fail << "unable to remove file " << f.string () << ": " << e.what (); + fail << "unable to remove file " << f << ": " << e.what (); } if (rs == rmfile_status::success) { - if (verb >= 1) - text << "rm " << f.string (); + if (verb) + text << "rm " << f; else text << "rm " << t; } @@ -62,21 +62,20 @@ namespace build } catch (const std::system_error& e) { - if (verb >= 1) - text << "rmdir " << d.string (); + if (verb) + text << "rmdir " << d; else text << "rmdir " << t; - fail << "unable to remove directory " << d.string () << ": " - << e.what (); + fail << "unable to remove directory " << d << ": " << e.what (); } switch (rs) { case rmdir_status::success: { - if (verb >= 1) - text << "rmdir " << d.string (); + if (verb) + text << "rmdir " << d; else text << "rmdir " << t; @@ -84,8 +83,8 @@ namespace build } case rmdir_status::not_empty: { - if (verb >= 1) - text << "directory " << d.string () << " is " + if (verb) + text << "directory " << d << " is " << (w ? "current working directory" : "not empty") << ", not removing"; diff --git a/build/cxx/module.cxx b/build/cxx/module.cxx index e5c71e7..846e324 100644 --- a/build/cxx/module.cxx +++ b/build/cxx/module.cxx @@ -61,7 +61,7 @@ namespace build // const char* args[] = {v.c_str (), "-dumpversion", nullptr}; - if (verb >= 1) + if (verb) print_process (args); else text << "test " << v; diff --git a/build/cxx/rule.cxx b/build/cxx/rule.cxx index a8a869f..963ecb1 100644 --- a/build/cxx/rule.cxx +++ b/build/cxx/rule.cxx @@ -278,7 +278,7 @@ namespace build assert (f.absolute ()); // Logic below depends on this. - level5 ([&]{trace << "prerequisite path: " << f.string ();}); + level5 ([&]{trace << "prerequisite path: " << f;}); // Split the name into its directory part, the name part, and // extension. Here we can assume the name part is a valid @@ -383,7 +383,7 @@ namespace build args.push_back (nullptr); - if (verb >= 1) + if (verb) print_process (args); else text << "c++ " << *s; @@ -758,7 +758,7 @@ namespace build args.push_back (nullptr); - if (verb >= 1) + if (verb) print_process (args); else text << "ld " << t; diff --git a/build/diagnostics b/build/diagnostics index 09adaca..85da45d 100644 --- a/build/diagnostics +++ b/build/diagnostics @@ -36,6 +36,17 @@ namespace build std::string diag_relative (const dir_path&, bool current = true); + // + // + extern const int relative_index; + + inline bool + relative (std::ostream& os) {return os.iword (relative_index);} + + inline void + relative (std::ostream& os, bool v) {os.iword (relative_index) = v ? 1 : 0;} + + // Action phrases, e.g., "configure update exe{foo}", "updating exe{foo}", // and "updating exe{foo} already configured". // @@ -154,6 +165,7 @@ namespace build if (!empty_) { + assert (false); //@@ Relative flag will not be transferred. os_ << r.os_.str (); r.empty_ = true; @@ -166,9 +178,11 @@ namespace build diag_record (const diag_record&) = delete; diag_record& operator= (const diag_record&) = delete; + public: + mutable std::ostringstream os_; + private: mutable bool empty_; - mutable std::ostringstream os_; mutable diag_epilogue epilogue_; }; @@ -235,8 +249,8 @@ namespace build struct simple_prologue_base { explicit - simple_prologue_base (const char* type, const char* name) - : type_ (type), name_ (name) {} + simple_prologue_base (const char* type, const char* name, bool rel) + : type_ (type), name_ (name), relative_ (rel) {} void operator() (const diag_record& r) const; @@ -244,6 +258,7 @@ namespace build private: const char* type_; const char* name_; + const bool relative_; }; typedef diag_prologue simple_prologue; @@ -262,8 +277,9 @@ namespace build { location_prologue_base (const char* type, const char* name, - const location& l) - : type_ (type), name_ (name), loc_ (l) {} + const location& l, + bool rel) + : type_ (type), name_ (name), loc_ (l), relative_ (rel) {} void operator() (const diag_record& r) const; @@ -272,9 +288,15 @@ namespace build const char* type_; const char* name_; const location loc_; + const bool relative_; }; typedef diag_prologue location_prologue; + // Here is the absolute/relative path rationale: we want it absolute + // in the error/warning/info streams to give the user the complete + // picture. But in the text stream (e.g., command lines), we print + // relative unless verbosity is greater than 0. + // struct basic_mark_base { explicit @@ -286,23 +308,23 @@ namespace build simple_prologue operator() () const { - return simple_prologue (type_, name_); + return simple_prologue (type_, name_, false); } location_prologue operator() (const location& l) const { - return location_prologue (type_, name_, l); + return location_prologue (type_, name_, l, false); } template location_prologue operator() (const L& l) const { - return location_prologue (type_, name_, get_location (l, data_)); + return location_prologue (type_, name_, get_location (l, data_), false); } - private: + protected: const char* type_; const char* name_; const void* data_; @@ -312,8 +334,25 @@ namespace build extern const basic_mark error; extern const basic_mark warn; extern const basic_mark info; - extern const basic_mark text; + // text + // + struct text_mark_base: basic_mark_base + { + text_mark_base (): basic_mark_base (nullptr) {} + + simple_prologue + operator() () const + { + return simple_prologue (type_, name_, verb == 0); + } + }; + typedef diag_mark text_mark; + + extern const text_mark text; + + // trace + // struct trace_mark_base: basic_mark_base { explicit @@ -324,6 +363,8 @@ namespace build typedef trace_mark tracer; + // fail + // template struct fail_mark_base { @@ -333,13 +374,13 @@ namespace build simple_prologue operator() () const { - return simple_prologue (&epilogue, "error", nullptr); + return simple_prologue (&epilogue, "error", nullptr, false); } location_prologue operator() (const location& l) const { - return location_prologue (&epilogue, "error", nullptr, l); + return location_prologue (&epilogue, "error", nullptr, l, false); } template @@ -347,7 +388,7 @@ namespace build operator() (const L& l) const { return location_prologue ( - &epilogue, "error", nullptr, get_location (l, data_)); + &epilogue, "error", nullptr, get_location (l, data_), false); } static void diff --git a/build/diagnostics.cxx b/build/diagnostics.cxx index bc157ed..0dfae1a 100644 --- a/build/diagnostics.cxx +++ b/build/diagnostics.cxx @@ -75,6 +75,10 @@ namespace build return r; } + // Relative stream. + // + const int relative_index = ostream::xalloc (); + // diag_do(), etc. // string @@ -194,6 +198,8 @@ namespace build void simple_prologue_base:: operator() (const diag_record& r) const { + relative (r.os_, relative_); + if (type_ != nullptr) r << type_ << ": "; @@ -204,6 +210,8 @@ namespace build void location_prologue_base:: operator() (const diag_record& r) const { + relative (r.os_, relative_); + r << loc_.file << ':' << loc_.line << ':' << loc_.column << ": "; if (type_ != nullptr) @@ -216,7 +224,6 @@ namespace build const basic_mark error ("error"); const basic_mark warn ("warning"); const basic_mark info ("info"); - const basic_mark text (nullptr); - + const text_mark text; const fail_mark fail; } diff --git a/build/dump.cxx b/build/dump.cxx index 75de2be..6496598 100644 --- a/build/dump.cxx +++ b/build/dump.cxx @@ -43,7 +43,7 @@ namespace build { // We don't want the extra notations (e.g., ~/) provided by // diag_relative() since we want the path to be relative to - // the outer scope. + // the global scope. // os << ind << relative (p.path ()) << ":" << endl << ind << '{'; diff --git a/build/parser.cxx b/build/parser.cxx index 06e489a..6c3989d 100644 --- a/build/parser.cxx +++ b/build/parser.cxx @@ -1024,7 +1024,7 @@ namespace build if (dp != nullptr) { if (n.dir.absolute ()) - fail (t) << "nested absolute directory " << n.dir.string () + fail (t) << "nested absolute directory " << n.dir << " in variable expansion"; d1 = *dp / n.dir; diff --git a/build/path-io b/build/path-io index accdb94..f5f2d4f 100644 --- a/build/path-io +++ b/build/path-io @@ -5,30 +5,17 @@ #ifndef BUILD_PATH_IO #define BUILD_PATH_IO -#include +#include #include namespace build { - inline std::ostream& - operator<< (std::ostream& os, const path& p) - { - return os << p.string (); - } + std::ostream& + operator<< (std::ostream&, const path&); - inline std::ostream& - operator<< (std::ostream& os, const dir_path& d) - { - const std::string& s (d.string ()); - - // Print the directory with trailing '/'. - // - if (!s.empty ()) - os << s << (dir_path::traits::is_separator (s.back ()) ? "" : "/"); - - return os; - } + std::ostream& + operator<< (std::ostream&, const dir_path&); } #endif // BUILD_PATH_IO diff --git a/build/path-io.cxx b/build/path-io.cxx new file mode 100644 index 0000000..80a14e0 --- /dev/null +++ b/build/path-io.cxx @@ -0,0 +1,38 @@ +// file : build/path-io.cxx -*- C++ -*- +// copyright : Copyright (c) 2014-2015 Code Synthesis Tools CC +// license : MIT; see accompanying LICENSE file + +#include + +#include + +#include + +using namespace std; + +namespace build +{ + ostream& + operator<< (ostream& os, const path& p) + { + return os << (relative (os) ? diag_relative (p) : p.string ()); + } + + ostream& + operator<< (ostream& os, const dir_path& d) + { + if (relative (os)) + os << diag_relative (d); + else + { + const string& s (d.string ()); + + // Print the directory with trailing '/'. + // + if (!s.empty ()) + os << s << (dir_path::traits::is_separator (s.back ()) ? "" : "/"); + } + + return os; + } +} diff --git a/build/rule.cxx b/build/rule.cxx index a9afe1b..03dd056 100644 --- a/build/rule.cxx +++ b/build/rule.cxx @@ -223,8 +223,8 @@ namespace build // if (!dir_exists (d)) { - if (verb >= 1) - text << "mkdir " << d.string (); + if (verb) + text << "mkdir " << d; else text << "mkdir " << t; @@ -234,8 +234,7 @@ namespace build } catch (const system_error& e) { - fail << "unable to create directory " << d.string () << ": " - << e.what (); + fail << "unable to create directory " << d << ": " << e.what (); } ts = target_state::changed; -- cgit v1.1