aboutsummaryrefslogtreecommitdiff
path: root/build2/config/operation.cxx
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2016-07-21 15:39:52 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2016-07-21 15:39:52 +0200
commitc1d08dbc56d0c8d3346deaba5d6b1946b6d711f4 (patch)
treede85880067c80e56d83de8e3902d95f2c2f9d7c5 /build2/config/operation.cxx
parent01fe759b58fbde7f8c7391122421dd08c754dc51 (diff)
Save config vars in order specified rather than alphabetically
This way we can group them semantically which results in easier to understand config.build output.
Diffstat (limited to 'build2/config/operation.cxx')
-rw-r--r--build2/config/operation.cxx270
1 files changed, 122 insertions, 148 deletions
diff --git a/build2/config/operation.cxx b/build2/config/operation.cxx
index 767ca1a..1b40832 100644
--- a/build2/config/operation.cxx
+++ b/build2/config/operation.cxx
@@ -87,192 +87,166 @@ namespace build2
ofs << "# Created automatically by the config module, but feel " <<
"free to edit." << endl
- << "#" << endl
- << endl;
+ << "#" << endl;
if (auto l = root.vars["amalgamation"])
{
const dir_path& d (cast<dir_path> (l));
- ofs << "# Base configuration inherited from " << d << endl
- << "#" << endl
- << endl;
+ ofs << endl
+ << "# Base configuration inherited from " << d << endl
+ << "#" << endl;
}
- // Separate variables for modules with blank lines.
- //
- const string* mod_s (nullptr);
- size_t mod_n (0);
-
- auto next_module = [&mod_s, &mod_n] (const variable& var) -> bool
- {
- const string& s (var.name);
-
- size_t p (s.find ('.', 7)); // 7 for "config."
- size_t n (p != string::npos ? p - 7 : s.size () - 7);
-
- if (mod_s == nullptr)
- {
- mod_s = &s;
- mod_n = n;
- return false; // First
- }
-
- if (s.compare (7, n, *mod_s, 7, mod_n) != 0)
- {
- mod_s = &s;
- mod_n = n;
- return true; // Next.
- }
-
- return false;
- };
-
// Save config variables.
//
names storage;
- for (auto b (mod.vars.begin ()), i (b), e (mod.vars.end ());
- i != e;
- ++i)
+ for (const saved_modules::const_iterator& i:
+ mod.saved_modules.sequence)
{
- const auto& p (*i);
- const variable& var (p.first);
- uint64_t sflags (p.second);
-
- pair<lookup, size_t> org (root.find_original (var));
- pair<lookup, size_t> ovr (var.override == nullptr
- ? org
- : root.find_override (var, org));
- const lookup& l (ovr.first);
-
- // We definitely write values that are set on our root scope or are
- // global overrides. Anything in-between is presumably inherited.
- // We might also not have any value at all (see unconfigured()).
+ const string& sname (i->first);
+ const saved_variables& svars (i->second);
+
+ // Separate modules with a blank line.
//
- if (!l.defined ())
- continue;
+ ofs << endl;
- if (!(l.belongs (root) || l.belongs (*global_scope)))
+ for (const saved_variable& sv: svars)
{
- // This is presumably an inherited value. But it could also be
- // some left-over garbage. For example, our amalgamation could
- // have used a module but then dropped it while its configuration
- // values are still lingering in config.build. They are probably
- // still valid and we should probably continue using them but we
- // definitely want to move them to our config.build since they
- // will be dropped from the amalgamation's config.build. Let's
- // also warn the user just in case.
+ const variable& var (sv.var);
+
+ pair<lookup, size_t> org (root.find_original (var));
+ pair<lookup, size_t> ovr (var.override == nullptr
+ ? org
+ : root.find_override (var, org));
+ const lookup& l (ovr.first);
+
+ // We definitely write values that are set on our root scope or
+ // are global overrides. Anything in-between is presumably
+ // inherited. We might also not have any value at all (see
+ // unconfigured()).
//
- bool found (false);
- scope* r (&root);
- while ((r = r->parent_scope ()->root_scope ()) != nullptr)
+ if (!l.defined ())
+ continue;
+
+ if (!(l.belongs (root) || l.belongs (*global_scope)))
{
- if (l.belongs (*r))
+ // This is presumably an inherited value. But it could also be
+ // some left-over garbage. For example, an amalgamation could
+ // have used a module but then dropped it while its config
+ // values are still lingering in config.build. They are probably
+ // still valid and we should probably continue using them but we
+ // definitely want to move them to our config.build since they
+ // will be dropped from the amalgamation's config.build. Let's
+ // also warn the user just in case.
+ //
+ bool found (false);
+ scope* r (&root);
+ while ((r = r->parent_scope ()->root_scope ()) != nullptr)
{
- if (auto* m = r->modules.lookup<const module> (module::name))
- found = m->vars.find (var) != m->vars.end ();
-
- break;
+ if (l.belongs (*r))
+ {
+ // Find config module.
+ //
+ if (auto* m = r->modules.lookup<const module> (module::name))
+ {
+ // Find the corresponding saved module.
+ //
+ auto i (m->saved_modules.find (sname));
+
+ if (i != m->saved_modules.end ())
+ {
+ // Find the variable. For now we do linear search.
+ //
+ const saved_variables& sv (i->second);
+ found = find_if (
+ sv.begin (),
+ sv.end (),
+ [&var] (const saved_variable& v) {
+ return var == v.var;}) != sv.end ();
+ }
+ }
+
+ break;
+ }
}
- }
-
- if (found) // Inherited.
- continue;
-
- location loc (&f);
- // If this value is not defined in a project's root scope, then
- // something is broken.
- //
- if (r == nullptr)
- fail (loc) << "inherited variable " << var.name << " value "
- << "is not from a root scope";
+ if (found) // Inherited.
+ continue;
- // If none of the outer project's configurations use this value,
- // then we warn and save as our own. One special case where we
- // don't want to warn the user is if the variable is overriden.
- //
- if (org.first == ovr.first)
- {
- diag_record dr;
- dr << warn (loc) << "saving previously inherited variable "
- << var.name;
+ location loc (&f);
- dr << info (loc) << "because project " << r->out_path ()
- << " no longer uses it in its configuration";
+ // If this value is not defined in a project's root scope, then
+ // something is broken.
+ //
+ if (r == nullptr)
+ fail (loc) << "inherited variable " << var.name << " value "
+ << "is not from a root scope";
- if (verb >= 2)
+ // If none of the outer project's configurations use this value,
+ // then we warn and save as our own. One special case where we
+ // don't want to warn the user is if the variable is overriden.
+ //
+ if (org.first == ovr.first)
{
- dr << info (loc) << "variable value: ";
+ diag_record dr;
+ dr << warn (loc) << "saving previously inherited variable "
+ << var.name;
- if (*l)
+ dr << info (loc) << "because project " << r->out_path ()
+ << " no longer uses it in its configuration";
+
+ if (verb >= 2)
{
- names storage;
- dr << "'" << reverse (*l, storage) << "'";
+ dr << info (loc) << "variable value: ";
+
+ if (*l)
+ {
+ storage.clear ();
+ dr << "'" << reverse (*l, storage) << "'";
+ }
+ else
+ dr << "[null]";
}
- else
- dr << "[null]";
}
}
- }
- const string& n (var.name);
- const value& v (*l);
+ const string& n (var.name);
+ const value& v (*l);
- // We will only write config.*.configured if it is false (true is
- // implied by its absence). We will also ignore false values if
- // there is any other value for this module (see unconfigured()).
- //
- if (n.size () > 11 &&
- n.compare (n.size () - 11, 11, ".configured") == 0)
- {
- if (cast<bool> (v))
- continue;
-
- size_t m (n.size () - 11); // Prefix size.
- auto same = [&n, m] (const variable& v)
- {
- return v.name.size () >= m &&
- v.name.compare (0, m, n, 0, m) == 0;
- };
-
- // Check if this is the first value for this module.
+ // We will only write config.*.configured if it is false (true is
+ // implied by its absence). We will also ignore false values if
+ // there is any other value for this module (see unconfigured()).
//
- auto j (i);
- if (j != b && same ((--j)->first))
- continue;
+ if (n.size () > 11 &&
+ n.compare (n.size () - 11, 11, ".configured") == 0)
+ {
+ if (cast<bool> (v) || svars.size () != 1)
+ continue;
+ }
- // Check if this is the last value for this module.
+ // Handle the save_commented flag.
//
- j = i;
- if (++j != e && same (j->first))
+ if ((org.first.defined () && org.first->extra) && // Default value.
+ org.first == ovr.first && // Not overriden.
+ (sv.flags & save_commented) == save_commented)
+ {
+ ofs << '#' << n << " =" << endl;
continue;
- }
-
- if (next_module (var))
- ofs << endl;
-
- // Handle the save_commented flag.
- //
- if ((org.first.defined () && org.first->extra) && // Default value.
- org.first == ovr.first && // Not overriden.
- (sflags & save_commented) == save_commented)
- {
- ofs << '#' << n << " =" << endl;
- continue;
- }
+ }
- if (v)
- {
- storage.clear ();
+ if (v)
+ {
+ storage.clear ();
- ofs << n << " = ";
- to_stream (ofs, reverse (v, storage), true, '@'); // Quote.
- ofs << endl;
+ ofs << n << " = ";
+ to_stream (ofs, reverse (v, storage), true, '@'); // Quote.
+ ofs << endl;
+ }
+ else
+ ofs << n << " = [null]" << endl;
}
- else
- ofs << n << " = [null]" << endl;
}
}
catch (const ofstream::failure&)