aboutsummaryrefslogtreecommitdiff
path: root/libbbot/build-config.cxx
diff options
context:
space:
mode:
authorKaren Arutyunov <karen@codesynthesis.com>2022-11-16 22:14:53 +0300
committerKaren Arutyunov <karen@codesynthesis.com>2022-11-23 14:08:05 +0300
commit40e4d161fa319a443c2598ddbc74b8ad31220c68 (patch)
treec5f8c20b135c297c386e9e544f303c991e3b40ab /libbbot/build-config.cxx
parent5d2f40dbca1ed021eb4586c8f3f5578825e82c57 (diff)
Add support for package-config task manifest value
Diffstat (limited to 'libbbot/build-config.cxx')
-rw-r--r--libbbot/build-config.cxx262
1 files changed, 0 insertions, 262 deletions
diff --git a/libbbot/build-config.cxx b/libbbot/build-config.cxx
deleted file mode 100644
index 15061fc..0000000
--- a/libbbot/build-config.cxx
+++ /dev/null
@@ -1,262 +0,0 @@
-// file : libbbot/build-config.cxx -*- C++ -*-
-// license : MIT; see accompanying LICENSE file
-
-#include <libbbot/build-config.hxx>
-
-#include <map>
-#include <string>
-#include <cstddef> // size_t
-#include <utility> // move(), make_pair()
-#include <stdexcept> // invalid_argument
-
-#include <libbutl/path.hxx>
-#include <libbutl/fdstream.hxx>
-#include <libbutl/tab-parser.hxx>
-#include <libbutl/string-parser.hxx>
-
-#include <libbpkg/manifest.hxx> // build_class_term::validate_name()
-
-#include <libbbot/manifest.hxx> // task_manifest::check_config()
-
-using namespace std;
-using namespace butl;
-
-namespace bbot
-{
- LIBBBOT_EXPORT build_configs
- parse_buildtab (istream& is, const string& name)
- {
- build_configs r;
- tab_parser parser (is, name);
-
- r.classes.push_back ("all");
- r.classes.push_back ("default");
-
- tab_fields tl;
- while (!(tl = parser.next ()).empty ())
- {
- size_t n (tl.size ()); // Fields count.
- size_t i (0); // The field currently being processed.
-
- // Throw tab_parsing for the field currently being processed. If i == n
- // then we refer to the end-of-line column (presumably reporting a missed
- // field).
- //
- auto bad_line = [&name, &tl, &i, n] (const string& d)
- {
- // Offset beyond the end-of-line is meaningless.
- //
- assert (i <= n);
-
- throw tab_parsing (name,
- tl.line,
- i == n
- ? tl.end_column
- : tl[i].column,
- d);
- };
-
- build_config config;
- config.machine_pattern = move (tl[i++].value);
-
- // If the machine pattern is a single dash character, then this is a
- // placeholder entry. The only thing we are interested about it is the
- // class inheritance information. Note that while all other information
- // is discarded, the configuration name and target must be present (can
- // also be dashes), so the classes field can be determined and parsed.
- //
- bool placeholder (config.machine_pattern == "-");
-
- // Configuration name, target[/environment] and classes fields are the
- // required ones.
- //
- if (i == n)
- bad_line ("no configuration name found");
-
- config.name = move (tl[i].value);
-
- if (++i == n)
- bad_line ("no target found");
-
- if (!placeholder)
- try
- {
- const string& v (tl[i].value);
-
- // Extract the environment name, if present.
- //
- size_t p (v.find ('/'));
-
- if (p != string::npos)
- {
- string env (v, p + 1);
-
- if (env.empty ())
- bad_line ("empty environment");
-
- config.environment = move (env);
- }
-
- // Parse the target triplet.
- //
- config.target = target_triplet (p != string::npos
- ? string (v, 0, p)
- : v);
- }
- catch (const invalid_argument& e)
- {
- bad_line (e.what ());
- }
-
- // Make sure the name/target combination is unique.
- //
- for (const auto& c: r)
- {
- if (c.name == config.name && c.target == config.target)
- bad_line ("duplicate configuration name/target");
- }
-
- if (++i == n)
- bad_line ("no classes found");
-
- // Parse a potentially quoted class list.
- //
- try
- {
- using namespace string_parser;
-
- auto validate = [] (const string& c)
- {
- bpkg::build_class_term::validate_name (c);
-
- if (c == "none")
- throw invalid_argument ("class 'none' is reserved");
- };
-
- // We don't expect the class names be quotes as they cannot contain
- // spaces.
- //
- for (string& c: parse_quoted (unquote (tl[i].value),
- false /* unquote */))
- {
- string base;
- size_t p (c.find (':'));
-
- if (p != string::npos)
- {
- base = string (c, p + 1);
- validate (base);
-
- c.resize (p);
- }
-
- validate (c);
-
- // Add the mapping of the derived class to its base.
- //
- // Note that it's not required for a base to also be registered in
- // the map.
- //
- auto i (r.class_inheritance_map.insert (make_pair (c, base)));
-
- // If the derived-to-base mapping is added, then verify that there
- // is no inheritance cycle. Otherwise, verify that the base class is
- // the same as for the existing mapping. Note that once the base
- // class is specified it can be omitted for subsequent mentions of
- // the derived class.
- //
- auto j (i.first);
-
- if (i.second) // Added?
- {
- // Traverse through the class hierarchy up until a non-registered
- // base (in particular an empty one) is encountered.
- //
- // Note: here we also handle the 'base of itself' case.
- //
- while (j != r.class_inheritance_map.end ())
- {
- const string& base (j->second);
-
- if (base == c)
- throw invalid_argument (
- "inheritance cycle in '" + c + "' class inheritance");
-
- j = r.class_inheritance_map.find (base);
- }
-
- if (c != "all" && c != "default")
- r.classes.push_back (c);
- }
- else if (j->second != base && !base.empty ())
- throw invalid_argument ('\'' + c + "' new base '" + base +
- "' does not match existing '" +
- j->second + '\'');
-
- if (!placeholder)
- config.classes.emplace_back (move (c));
- }
- }
- catch (const invalid_argument& e)
- {
- bad_line (e.what ());
- }
-
- // We are done if this is a placeholder.
- //
- if (placeholder)
- continue;
-
- // Parse options, variables, and regexes.
- //
- try
- {
- for (++i; i < n; ++i)
- {
- string& v (tl[i].value);
-
- if (v[0] == '~') // Regular expression.
- {
- string re (v, 1);
- task_manifest::validate_regex (re);
- config.warning_regexes.emplace_back (move (re));
- }
- else // Configuration option or variable.
- config.args.emplace_back (move (v));
- }
- }
- catch (const invalid_argument& e)
- {
- bad_line (e.what ());
- }
-
- // Save the configuration.
- //
- r.emplace_back (move (config));
- }
-
- // Erase entries for baseless classes (we were collecting them to make
- // sure that the class inheritance is consistent across configurations).
- //
- for (auto i (r.class_inheritance_map.begin ());
- i != r.class_inheritance_map.end (); )
- {
- if (i->second.empty ())
- i = r.class_inheritance_map.erase (i);
- else
- ++i;
- }
-
- return r;
- }
-
- build_configs
- parse_buildtab (const path& p)
- {
- ifdstream ifs (p);
- build_configs r (parse_buildtab (ifs, p.string ()));
-
- ifs.close (); // Throws on failure.
- return r;
- }
-}