aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2017-12-16 14:14:15 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2017-12-16 14:14:15 +0200
commit530e8914ba00ce0e7ee89ba30d2b88f2c09f43c9 (patch)
tree0ca06c48d30ae06d8407da34bd02c57140b71062
parent44e1022f8141bd57756c2be4277c728ca7443eb3 (diff)
Split stream verbosity into components (path, extension)
Use to make sure structured result output always contains absolute target path.
-rw-r--r--build2/b.cxx13
-rw-r--r--build2/diagnostics.hxx81
-rw-r--r--build2/dump.cxx51
-rw-r--r--build2/name.cxx6
-rw-r--r--build2/parser.cxx7
-rw-r--r--build2/prerequisite.cxx2
-rw-r--r--build2/spec.cxx2
-rw-r--r--build2/target-key.hxx5
-rw-r--r--build2/target.cxx26
-rw-r--r--build2/utility.cxx2
-rw-r--r--unit-tests/name/driver.cxx2
11 files changed, 112 insertions, 85 deletions
diff --git a/build2/b.cxx b/build2/b.cxx
index 0d88f5f..7bb9484 100644
--- a/build2/b.cxx
+++ b/build2/b.cxx
@@ -105,16 +105,17 @@ namespace build2
// Let's go with the portable one for now and see how it goes (we
// can always add a format version, e.g., --structured-result=2).
- // Set the stream verbosity to 0 to suppress extension printing by
- // default (this can still be overriden by the target type's print
- // function as is the case for file{}, for example).
+ // Set the stream extension verbosity to 0 to suppress extension
+ // printing by default (this can still be overriden by the target
+ // type's print function as is the case for file{}, for example).
+ // And set the path verbosity to 1 to always print absolute.
//
- uint16_t v (stream_verb (cout));
- stream_verb (cout, 0);
+ stream_verbosity sv (stream_verb (cout));
+ stream_verb (cout, stream_verbosity (1, 0));
cout << ' ' << at.as_target () << endl;
- stream_verb (cout, v);
+ stream_verb (cout, sv);
}
}
}
diff --git a/build2/diagnostics.hxx b/build2/diagnostics.hxx
index 65b1834..9a020d3 100644
--- a/build2/diagnostics.hxx
+++ b/build2/diagnostics.hxx
@@ -69,44 +69,75 @@ namespace build2
template <typename F> inline void l5 (const F& f) {if (verb >= 5) f ();}
template <typename F> inline void l6 (const F& f) {if (verb >= 6) f ();}
- // Stream verbosity level. It is determined by the diagnostic type (e.g.,
- // trace always has maximum verbosity) as well as the program verbosity. It
- // is used to decide whether to print relative/absolute paths, and default
+ // Stream verbosity level. Determined by the diagnostic type (e.g., trace
+ // always has maximum verbosity) as well as the program verbosity. It is
+ // used to decide whether to print relative/absolute paths and default
// target extensions.
//
- // 0 - minimum
- // 1 - intermediate
- // 2 - maximum
- //
// Currently we have the following program to stream verbosity mapping:
//
- // fail/error/warn/info <2:0 2:1 >2:2
- // trace *:2
+ // fail/error/warn/info <2:{0,0} 2:{0,1} >2:{1,2}
+ // trace *:{1,2}
//
// A stream that hasn't been (yet) assigned any verbosity explicitly (e.g.,
// ostringstream) defaults to maximum.
//
- const uint16_t stream_verb_min = 0;
- const uint16_t stream_verb_max = 2;
+ struct stream_verbosity
+ {
+ union
+ {
+ struct
+ {
+ // 0 - print relative.
+ // 1 - print absolute.
+ //
+ uint16_t path: 1;
+
+ // 0 - don't print.
+ // 1 - print if specified.
+ // 2 - print as 'foo.?' if unspecified and 'foo.' if specified as
+ // "no extension" (empty).
+ //
+ uint16_t extension: 2;
+ };
+ uint16_t value_;
+ };
+
+ constexpr
+ stream_verbosity (uint16_t p, uint16_t e): path (p), extension (e) {}
+
+ explicit
+ stream_verbosity (uint16_t v = 0): value_ (v) {}
+ };
+
+ constexpr stream_verbosity stream_verb_max = {1, 2};
// Default program to stream verbosity mapping, as outlined above.
//
- inline uint16_t
- stream_verb_map () {return verb < 2 ? 0 : (verb > 2 ? 2 : 1);}
+ inline stream_verbosity
+ stream_verb_map ()
+ {
+ return
+ verb < 2 ? stream_verbosity (0, 0) :
+ verb > 2 ? stream_verbosity (1, 2) :
+ /* */ stream_verbosity (0, 1);
+ }
extern const int stream_verb_index;
- inline uint16_t
+ inline stream_verbosity
stream_verb (ostream& os)
{
- uint16_t v (static_cast<uint16_t> (os.iword (stream_verb_index)));
- return v == 0 ? stream_verb_max : v - 1;
+ long v (os.iword (stream_verb_index));
+ return v == 0
+ ? stream_verb_max
+ : stream_verbosity (static_cast<uint16_t> (v - 1));
}
inline void
- stream_verb (ostream& os, uint16_t v)
+ stream_verb (ostream& os, stream_verbosity v)
{
- os.iword (stream_verb_index) = static_cast<long> (v + 1);
+ os.iword (stream_verb_index) = static_cast<long> (v.value_) + 1;
}
// Diagnostic facility, base infrastructure.
@@ -187,7 +218,7 @@ namespace build2
simple_prologue_base (const char* type,
const char* mod,
const char* name,
- uint16_t sverb)
+ stream_verbosity sverb)
: type_ (type), mod_ (mod), name_ (name), sverb_ (sverb) {}
void
@@ -197,7 +228,7 @@ namespace build2
const char* type_;
const char* mod_;
const char* name_;
- const uint16_t sverb_;
+ const stream_verbosity sverb_;
};
class location
@@ -224,7 +255,7 @@ namespace build2
const char* mod,
const char* name,
const location& l,
- uint16_t sverb)
+ stream_verbosity sverb)
: type_ (type), mod_ (mod), name_ (name),
loc_ (l),
sverb_ (sverb) {}
@@ -233,7 +264,7 @@ namespace build2
const char* mod,
const char* name,
path&& f,
- uint16_t sverb)
+ stream_verbosity sverb)
: type_ (type), mod_ (mod), name_ (name),
file_ (move (f)), loc_ (&file_),
sverb_ (sverb) {}
@@ -247,7 +278,7 @@ namespace build2
const char* name_;
const path file_;
const location loc_;
- const uint16_t sverb_;
+ const stream_verbosity sverb_;
};
struct basic_mark_base
@@ -259,7 +290,7 @@ namespace build2
basic_mark_base (const char* type,
const void* data = nullptr,
diag_epilogue* epilogue = &diag_frame::apply,
- uint16_t (*sverb) () = &stream_verb_map,
+ stream_verbosity (*sverb) () = &stream_verb_map,
const char* mod = nullptr,
const char* name = nullptr)
: sverb_ (sverb),
@@ -296,7 +327,7 @@ namespace build2
}
protected:
- uint16_t (*sverb_) ();
+ stream_verbosity (*sverb_) ();
const char* type_;
const char* mod_;
const char* name_;
diff --git a/build2/dump.cxx b/build2/dump.cxx
index 714ae05..3f5aced 100644
--- a/build2/dump.cxx
+++ b/build2/dump.cxx
@@ -194,22 +194,18 @@ namespace build2
string& ind,
const target& t,
const scope& s,
- bool relative)
+ bool rel)
{
// If requested, print the target and its prerequisites relative to the
// scope. To achieve this we are going to temporarily lower the stream
- // verbosity to level 1. The drawback of doing this is that we also lower
- // the verbosity of extension printing (it wouldn't have been bad at all
- // to get 'foo.?' for unassigned and 'foo.' for empty).
+ // path verbosity to level 0.
//
- // @@ Actually, all those foo.? look rather hairy...
- // @@ Can't we change level to a bit mask?
- //
- uint16_t sv;
- if (relative)
+ stream_verbosity osv, nsv;
+ if (rel)
{
- sv = stream_verb (os);
- stream_verb (os, 1);
+ osv = nsv = stream_verb (os);
+ nsv.path = 0;
+ stream_verb (os, nsv);
}
if (t.group != nullptr)
@@ -221,8 +217,8 @@ namespace build2
//
if (!t.vars.empty ())
{
- if (relative)
- stream_verb (os, sv); // We want variable values in full.
+ if (rel)
+ stream_verb (os, osv); // We want variable values in full.
os << endl
<< ind << '{';
@@ -232,8 +228,8 @@ namespace build2
os << endl
<< ind << '}';
- if (relative)
- stream_verb (os, 1);
+ if (rel)
+ stream_verb (os, nsv);
os << endl
<< ind << t << ':';
@@ -293,8 +289,8 @@ namespace build2
if (ps)
{
- if (relative)
- stream_verb (os, sv); // We want variable values in full.
+ if (rel)
+ stream_verb (os, osv); // We want variable values in full.
os << ':' << endl
<< ind << '{';
@@ -304,8 +300,8 @@ namespace build2
os << endl
<< ind << '}';
- if (relative)
- stream_verb (os, 1);
+ if (rel)
+ stream_verb (os, nsv);
if (i != e) // If we have another, get a new header.
os << endl
@@ -315,12 +311,15 @@ namespace build2
used = !ps;
}
- if (relative)
- stream_verb (os, sv);
+ if (rel)
+ stream_verb (os, osv);
}
static void
- dump_scope (ostream& os, string& ind, scope_map::const_iterator& i)
+ dump_scope (ostream& os,
+ string& ind,
+ scope_map::const_iterator& i,
+ bool rel)
{
const scope& p (i->second);
const dir_path& d (i->first);
@@ -335,7 +334,7 @@ namespace build2
os << ind << dir_path::traits::directory_separator;
else
{
- dir_path rd (relative (d));
+ const dir_path& rd (rel ? relative (d) : d);
os << ind << (rd.empty () ? dir_path (".") : rd);
}
@@ -381,7 +380,7 @@ namespace build2
os << endl; // Extra newline between scope blocks.
os << endl;
- dump_scope (os, ind, i);
+ dump_scope (os, ind, i, true /* relative */);
sb = true;
}
@@ -426,7 +425,7 @@ namespace build2
//
string ind;
ostream& os (*diag_stream);
- dump_scope (os, ind, i);
+ dump_scope (os, ind, i, false /* relative */);
os << endl;
}
@@ -439,7 +438,7 @@ namespace build2
string ind (cind);
ostream& os (*diag_stream);
- dump_scope (os, ind, i);
+ dump_scope (os, ind, i, false /* relative */);
os << endl;
}
diff --git a/build2/name.cxx b/build2/name.cxx
index f71c7c1..5621101 100644
--- a/build2/name.cxx
+++ b/build2/name.cxx
@@ -96,11 +96,11 @@ namespace build2
os << v;
};
- uint16_t dv (stream_verb (os)); // Directory verbosity.
+ uint16_t dv (stream_verb (os).path); // Directory verbosity.
auto write_dir = [dv, quote, &os, &write_string] (const dir_path& d)
{
- const string& s (dv < 2
+ const string& s (dv < 1
? diag_relative (d)
: d.representation ());
if (quote)
@@ -133,7 +133,7 @@ namespace build2
// Note: relative() may return empty.
//
- const dir_path& rd (dv < 2 ? relative (n.dir) : n.dir); // Relative.
+ const dir_path& rd (dv < 1 ? relative (n.dir) : n.dir); // Relative.
const dir_path& pd (v ? rd :
t ? rd.directory () :
dir_path ());
diff --git a/build2/parser.cxx b/build2/parser.cxx
index 1f2ab9d..48902b8 100644
--- a/build2/parser.cxx
+++ b/build2/parser.cxx
@@ -1883,11 +1883,6 @@ namespace build2
//
ostream& os (*diag_stream);
- // Print directories as absolute.
- //
- const dir_path* orb (relative_base);
- relative_base = &empty_dir_path;
-
if (ns.empty ())
{
if (scope_ != nullptr)
@@ -1918,8 +1913,6 @@ namespace build2
}
}
- relative_base = orb;
-
if (tt != type::eos)
next (t, tt); // Swallow newline.
}
diff --git a/build2/prerequisite.cxx b/build2/prerequisite.cxx
index 6233ec4..b8c1791 100644
--- a/build2/prerequisite.cxx
+++ b/build2/prerequisite.cxx
@@ -34,7 +34,7 @@ namespace build2
//
const dir_path& s (pk.scope->out_path ());
- if (stream_verb (os) < 2)
+ if (stream_verb (os).path < 1)
{
const string& r (diag_relative (s, false));
diff --git a/build2/spec.cxx b/build2/spec.cxx
index da581c8..0e5bd75 100644
--- a/build2/spec.cxx
+++ b/build2/spec.cxx
@@ -19,7 +19,7 @@ namespace build2
// Avoid printing './' in './@...', similar to what we do for the
// {target,prerequisite}_key.
//
- if (stream_verb (os) < 2)
+ if (stream_verb (os).path < 1)
{
const string& r (diag_relative (s.src_base, false));
diff --git a/build2/target-key.hxx b/build2/target-key.hxx
index f37713e..d9ae57c 100644
--- a/build2/target-key.hxx
+++ b/build2/target-key.hxx
@@ -72,14 +72,13 @@ namespace build2
operator!= (const target_key& x, const target_key& y) {return !(x == y);}
// If the target type has a custom print function, call that. Otherwise,
- // call to_stream() with the current stream verbosity as a third argument.
- // Both are defined in target.cxx.
+ // call to_stream(). Both are defined in target.cxx.
//
ostream&
operator<< (ostream&, const target_key&);
ostream&
- to_stream (ostream&, const target_key&, uint16_t ext_verb);
+ to_stream (ostream&, const target_key&, optional<stream_verbosity> = nullopt);
}
namespace std
diff --git a/build2/target.cxx b/build2/target.cxx
index 99c002b..90b2511 100644
--- a/build2/target.cxx
+++ b/build2/target.cxx
@@ -307,7 +307,7 @@ namespace build2
r << "assuming target ";
to_stream (r.os,
target_key {&t.type (), &t.dir, &t.out, &t.name, ext},
- 2); // Always print the extension.
+ stream_verb_max); // Always print the extension.
r << " is the same as the one with ";
if (!k.ext)
@@ -382,7 +382,7 @@ namespace build2
to_stream (
r.os,
target_key {&t->type (), &t->dir, &t->out, &t->name, ext},
- 2); // Always print the extension.
+ stream_verb_max); // Always print the extension.
r << " is the same as the one with ";
if (!e)
@@ -416,9 +416,11 @@ namespace build2
}
ostream&
- to_stream (ostream& os, const target_key& k, uint16_t ev)
+ to_stream (ostream& os, const target_key& k, optional<stream_verbosity> osv)
{
- uint16_t dv (stream_verb (os)); // Directory verbosity.
+ stream_verbosity sv (osv ? *osv : stream_verb (os));
+ uint16_t dv (sv.path);
+ uint16_t ev (sv.extension);
// If the name is empty, then we want to print the last component of the
// directory inside {}, e.g., dir{bar/}, not bar/dir{}.
@@ -427,12 +429,12 @@ namespace build2
// Note: relative() returns empty for './'.
//
- const dir_path& rd (dv < 2 ? relative (*k.dir) : *k.dir); // Relative.
+ const dir_path& rd (dv < 1 ? relative (*k.dir) : *k.dir); // Relative.
const dir_path& pd (n ? rd : rd.directory ()); // Parent.
if (!pd.empty ())
{
- if (dv < 2)
+ if (dv < 1)
os << diag_relative (pd);
else
os << pd.representation ();
@@ -472,7 +474,7 @@ namespace build2
//
if (!k.out->empty ())
{
- if (dv < 2)
+ if (dv < 1)
{
// Don't print '@./'.
//
@@ -666,15 +668,17 @@ namespace build2
void
target_print_0_ext_verb (ostream& os, const target_key& k)
{
- uint16_t v (stream_verb (os));
- to_stream (os, k, v < 2 ? 0 : v); // Remap 1 to 0.
+ stream_verbosity sv (stream_verb (os));
+ if (sv.extension == 1) sv.extension = 0; // Remap 1 to 0.
+ to_stream (os, k, sv);
}
void
target_print_1_ext_verb (ostream& os, const target_key& k)
{
- uint16_t v (stream_verb (os));
- to_stream (os, k, v < 1 ? 1 : v); // Remap 0 to 1.
+ stream_verbosity sv (stream_verb (os));
+ if (sv.extension == 0) sv.extension = 1; // Remap 0 to 1.
+ to_stream (os, k, sv);
}
// type info
diff --git a/build2/utility.cxx b/build2/utility.cxx
index d11b46d..df19b92 100644
--- a/build2/utility.cxx
+++ b/build2/utility.cxx
@@ -38,7 +38,7 @@ namespace std
{
using namespace build2;
- return os << (stream_verb (os) < 2
+ return os << (stream_verb (os).path < 1
? diag_relative (p)
: p.representation ());
}
diff --git a/unit-tests/name/driver.cxx b/unit-tests/name/driver.cxx
index d454685..57d9c3c 100644
--- a/unit-tests/name/driver.cxx
+++ b/unit-tests/name/driver.cxx
@@ -48,7 +48,7 @@ namespace build2
auto ts = [] (const name& n, bool quote = true)
{
ostringstream os;
- stream_verb (os, 1);
+ stream_verb (os, stream_verbosity (0, 1));
to_stream (os, n, quote);
return os.str ();
};