| /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying | |
| file LICENSE.rst or https://cmake.org/licensing for details. */ | |
| #include "cmDiagnostics.h" | |
| #include <cassert> | |
| #include <map> | |
| #include <string> | |
| #include <utility> | |
| #include <cmext/string_view> | |
| #include "cmStringAlgorithms.h" | |
| namespace { | |
| #if __cplusplus >= 201703L | |
| constexpr unsigned validateDiagnosticsSubtree(unsigned parent, unsigned index) | |
| { | |
| // Ensure that all diagnostics, starting from the specified index, have the | |
| // specified parent as an ancestor. Return the first index that violates | |
| // this condition. | |
| while (index < cmDiagnostics::CategoryCount && | |
| cmDiagnostics::CategoryInfo[index].Parent == parent) { | |
| unsigned const child = index; | |
| // For each diagnostic, 'consume' its children (if any). | |
| index = validateDiagnosticsSubtree(child, ++index); | |
| } | |
| return index; | |
| } | |
| static_assert(validateDiagnosticsSubtree(cmDiagnostics::CMD_NONE, 1) == | |
| cmDiagnostics::CategoryCount, | |
| "Diagnostics are not properly ordered" | |
| " (hint: LHS is the index of the first misordered diagnostic)"); | |
| #endif | |
| cm::optional<cmDiagnosticCategory> stringToCategory(cm::string_view input) | |
| { | |
| using Map = std::map<cm::string_view, cmDiagnosticCategory>; | |
| static Map const mapping = { | |
| #define CATEGORY_MAP(C) { #C ""_s, cmDiagnostics::C }, | |
| CM_FOR_EACH_DIAGNOSTIC_CATEGORY(CATEGORY_MAP) | |
| #undef CATEGORY_MAP | |
| }; | |
| assert(!input.empty()); | |
| if (input.size() >= 4 && cmHasLiteralPrefix(input, "CMD_")) { | |
| auto const i = mapping.find(input); | |
| if (i != mapping.end()) { | |
| return i->second; | |
| } | |
| } | |
| return cm::nullopt; | |
| } | |
| } | |
| #if __cplusplus < 201703L | |
| // Prior to C++17, the compiler is unhappy if this member doesn't have explicit | |
| // storage... and clang-tidy is unhappy if it does. | |
| // NOLINTNEXTLINE(*-redundant-declaration) | |
| constexpr cmDiagnostics::DiagnosticCategoryInformation | |
| cmDiagnostics::CategoryInfo[cmDiagnostics::CategoryCount]; | |
| #endif | |
| cm::string_view cmDiagnostics::GetActionString(DiagnosticAction action) | |
| { | |
| switch (action) { | |
| case Ignore: | |
| return "IGNORE"_s; | |
| case Warn: | |
| return "WARN"_s; | |
| case SendError: | |
| return "SEND_ERROR"_s; | |
| case FatalError: | |
| return "FATAL_ERROR"_s; | |
| default: | |
| return {}; | |
| } | |
| } | |
| cm::string_view cmDiagnostics::GetCategoryString(DiagnosticCategory category) | |
| { | |
| static cm::string_view const names[CategoryCount] = { | |
| {}, // CMD_NONE | |
| #define CATEGORY_NAME(C) #C ""_s, | |
| CM_FOR_EACH_DIAGNOSTIC_CATEGORY(CATEGORY_NAME) | |
| #undef CATEGORY_MAP | |
| }; | |
| if (category < CategoryCount) { | |
| return names[category]; | |
| } | |
| return {}; | |
| } | |
| cm::optional<cmDiagnosticAction> cmDiagnostics::GetDiagnosticAction( | |
| cm::string_view name) | |
| { | |
| if (name == "IGNORE"_s) { | |
| return DiagnosticAction::Ignore; | |
| } | |
| if (name == "WARN"_s) { | |
| return DiagnosticAction::Warn; | |
| } | |
| if (name == "SEND_ERROR"_s) { | |
| return DiagnosticAction::SendError; | |
| } | |
| if (name == "FATAL_ERROR"_s) { | |
| return DiagnosticAction::FatalError; | |
| } | |
| return cm::nullopt; | |
| } | |
| cm::optional<cmDiagnosticCategory> cmDiagnostics::GetDiagnosticCategory( | |
| cm::string_view name) | |
| { | |
| return stringToCategory(name); | |
| } |