aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2015-04-20 13:01:46 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2015-04-20 13:01:46 +0200
commita82cdb8fd9ba02034d296769772cdf81244da66a (patch)
tree2cd5fb0211984716780ce5fad18c19d7c4d9a794
parentc775a7f28a56ef96f097e677434eceec9d8f2cdf (diff)
Automatically decide when to print relative/absolute paths
-rw-r--r--build/buildfile4
-rw-r--r--build/config/operation.cxx12
-rw-r--r--build/context.cxx16
-rw-r--r--build/context.txx25
-rw-r--r--build/cxx/module.cxx2
-rw-r--r--build/cxx/rule.cxx6
-rw-r--r--build/diagnostics67
-rw-r--r--build/diagnostics.cxx11
-rw-r--r--build/dump.cxx2
-rw-r--r--build/parser.cxx2
-rw-r--r--build/path-io23
-rw-r--r--build/path-io.cxx38
-rw-r--r--build/rule.cxx7
13 files changed, 135 insertions, 80 deletions
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_base> 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_base> 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 <typename L>
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_base> 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 <typename E>
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 <typename L>
@@ -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<failed> 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 <ostream>
+#include <iosfwd>
#include <build/path>
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 <build/path-io>
+
+#include <ostream>
+
+#include <build/diagnostics>
+
+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;