// file : libbbot/build-config.cxx -*- C++ -*- // copyright : Copyright (c) 2014-2017 Code Synthesis Ltd // license : MIT; see accompanying LICENSE file #include #include #include // size_t #include // move() #include // invalid_argument #include #include #include #include // 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); 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); // Configuration name field is a required one. // if (i == n) bad_line ("no configuration name found"); config.name = move (tl[i].value); // Make sure the name is unique. // for (const auto& c: r) { if (c.name == config.name) bad_line ("duplicate configuration name"); } if (++i == n) bad_line ("no target found"); try { config.target = target_triplet (tl[i].value); } catch (const invalid_argument& e) { bad_line (e.what ()); } try { for (++i; i < n; ++i) { string& v (tl[i].value); if (v[0] == '~') // Regular expression. { string re (v, 1); task_manifest::check_regex (re); config.warning_regexes.emplace_back (move (re)); } else // Configuration variable. { task_manifest::check_config (v); config.vars.emplace_back (move (v)); } } } catch (const invalid_argument& e) { bad_line (e.what ()); } // Save the configuration. // r.emplace_back (move (config)); } 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; } }