diff options
author | Karen Arutyunov <karen@codesynthesis.com> | 2022-11-16 22:14:53 +0300 |
---|---|---|
committer | Karen Arutyunov <karen@codesynthesis.com> | 2022-11-23 14:08:05 +0300 |
commit | 40e4d161fa319a443c2598ddbc74b8ad31220c68 (patch) | |
tree | c5f8c20b135c297c386e9e544f303c991e3b40ab /libbbot/build-config.cxx | |
parent | 5d2f40dbca1ed021eb4586c8f3f5578825e82c57 (diff) |
Add support for package-config task manifest value
Diffstat (limited to 'libbbot/build-config.cxx')
-rw-r--r-- | libbbot/build-config.cxx | 262 |
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; - } -} |