| @@ -0,0 +1,6 @@ | |||
| Error: Invalid configuration key | |||
| ################################ | |||
| ``dds`` uses a very simple key-value-pair plaintext configuration file format. | |||
| Receiving this error indicates that one of the keys in a configuration file is | |||
| invalid. | |||
| @@ -1,5 +1,6 @@ | |||
| #include "./deps.hpp" | |||
| #include <dds/dym.hpp> | |||
| #include <dds/error/errors.hpp> | |||
| #include <dds/repo/repo.hpp> | |||
| #include <dds/source/dist.hpp> | |||
| @@ -53,7 +54,7 @@ dependency_manifest dependency_manifest::from_file(path_ref fpath) { | |||
| } | |||
| return false; | |||
| }, | |||
| lm::reject_unknown()); | |||
| lm_reject_dym{{"Depends"}}); | |||
| return ret; | |||
| } | |||
| @@ -1,5 +1,7 @@ | |||
| #include <dds/dym.hpp> | |||
| #include <dds/error/errors.hpp> | |||
| #include <range/v3/algorithm/min_element.hpp> | |||
| #include <range/v3/view/cartesian_product.hpp> | |||
| #include <range/v3/view/iota.hpp> | |||
| @@ -43,3 +45,13 @@ std::size_t dds::lev_edit_distance(std::string_view a, std::string_view b) noexc | |||
| return matrix.back().back(); | |||
| } | |||
| bool lm_reject_dym::operator()(std::string_view context, | |||
| std::string_view key, | |||
| std::string_view) const { | |||
| assert(candidates.size() > 0); | |||
| throw_user_error<errc::invalid_config_key>("{}: Unknown key '{}' (Did you meann '{}'?)", | |||
| context, | |||
| key, | |||
| *did_you_mean(key, candidates)); | |||
| } | |||
| @@ -58,4 +58,11 @@ did_you_mean(std::string_view given, std::initializer_list<std::string_view> str | |||
| return did_you_mean(given, ranges::views::all(strings)); | |||
| } | |||
| struct lm_reject_dym { | |||
| std::initializer_list<std::string_view> candidates; | |||
| [[noreturn]] bool | |||
| operator()(std::string_view context, std::string_view key, std::string_view value) const; | |||
| }; | |||
| } // namespace dds | |||
| @@ -43,6 +43,8 @@ std::string error_url_suffix(dds::errc ec) noexcept { | |||
| return "invalid-version-string.html#range"; | |||
| case errc::invalid_version_string: | |||
| return "invalid-version-string.html"; | |||
| case errc::invalid_config_key: | |||
| return "invalid-config-key.html"; | |||
| case errc::none: | |||
| break; | |||
| } | |||
| @@ -153,6 +155,8 @@ information. | |||
| specification. Refer to the documentation and https://semver.org/ for more | |||
| information. | |||
| )"; | |||
| case errc::invalid_config_key: | |||
| return R"(The `key' in a `key: value' pair was not recognized.)"; | |||
| case errc::none: | |||
| break; | |||
| } | |||
| @@ -198,6 +202,9 @@ std::string_view dds::default_error_string(dds::errc ec) noexcept { | |||
| case errc::invalid_version_string: | |||
| return "Attempted to parse an invalid version string. <- (Seeing this text is a `dds` bug. " | |||
| "Please report it.)"; | |||
| case errc::invalid_config_key: | |||
| return "Found an invalid configuration key. <- (Seeing this text is a `dds` bug. Please " | |||
| "report it.)"; | |||
| case errc::none: | |||
| break; | |||
| } | |||
| @@ -29,6 +29,7 @@ enum class errc { | |||
| invalid_version_range_string, | |||
| invalid_version_string, | |||
| invalid_config_key, | |||
| }; | |||
| std::string error_reference_of(errc) noexcept; | |||
| @@ -1,5 +1,6 @@ | |||
| #include "./manifest.hpp" | |||
| #include <dds/dym.hpp> | |||
| #include <dds/util/algo.hpp> | |||
| #include <range/v3/view/transform.hpp> | |||
| @@ -20,8 +21,7 @@ library_manifest library_manifest::load_from_file(const fs::path& fpath) { | |||
| lm::read_accumulate("Uses", uses_strings), | |||
| lm::read_accumulate("Links", links_strings), | |||
| lm::read_required("Name", ret.name), | |||
| lm::ignore_x_keys(), | |||
| lm::reject_unknown()); | |||
| lm_reject_dym{{"Uses", "Links", "Name"}}); | |||
| extend(ret.uses, ranges::views::transform(uses_strings, lm::split_usage_string)); | |||
| extend(ret.links, ranges::views::transform(links_strings, lm::split_usage_string)); | |||
| @@ -1,5 +1,6 @@ | |||
| #include "./manifest.hpp" | |||
| #include <dds/dym.hpp> | |||
| #include <dds/util/string.hpp> | |||
| #include <libman/parse.hpp> | |||
| @@ -23,7 +24,7 @@ package_manifest package_manifest::load_from_file(const fs::path& fpath) { | |||
| lm::read_required("Version", version_str), | |||
| lm::read_accumulate("Depends", depends_strs), | |||
| lm::read_opt("Test-Driver", opt_test_driver), | |||
| lm::reject_unknown()); | |||
| lm_reject_dym{{"Name", "Namespace", "Version", "Depends", "Test-Driver"}}); | |||
| if (ret.pkg_id.name.empty()) { | |||
| throw std::runtime_error( | |||
| @@ -1,5 +1,6 @@ | |||
| #include "./from_dds.hpp" | |||
| #include <dds/dym.hpp> | |||
| #include <dds/toolchain/prep.hpp> | |||
| #include <dds/toolchain/toolchain.hpp> | |||
| #include <dds/util/algo.hpp> | |||
| @@ -146,7 +147,35 @@ toolchain dds::parse_toolchain_dds(const lm::pair_list& pairs, strv context) { | |||
| lm::read_opt("Executable-Prefix", exe_prefix), | |||
| lm::read_opt("Executable-Suffix", exe_suffix), | |||
| // Die: | |||
| lm::reject_unknown()); | |||
| lm_reject_dym{{ | |||
| "Compiler-ID", | |||
| "C-Compiler", | |||
| "C++-Compiler", | |||
| "C-Version", | |||
| "C++-Version", | |||
| "Include-Template", | |||
| "External-Include-Template", | |||
| "Define-Template", | |||
| "Warning-Flags", | |||
| "Flags", | |||
| "C-Flags", | |||
| "C++-Flags", | |||
| "Link-Flags", | |||
| "Optimize", | |||
| "Debug", | |||
| "Compiler-Launcher", | |||
| "Deps-Mode", | |||
| "C-Compile-File", | |||
| "C++-Compile-File", | |||
| "Create-Archive", | |||
| "Link-Executable", | |||
| "Archive-Prefix", | |||
| "Archive-Suffix", | |||
| "Object-Prefix", | |||
| "Object-Suffix", | |||
| "Executable-Prefix", | |||
| "Executable-Suffix", | |||
| }}); | |||
| toolchain_prep tc; | |||