/src/CMake/Source/cmDiagnostics.cxx
Line | Count | Source |
1 | | /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying |
2 | | file LICENSE.rst or https://cmake.org/licensing for details. */ |
3 | | #include "cmDiagnostics.h" |
4 | | |
5 | | #include <cassert> |
6 | | #include <map> |
7 | | #include <string> |
8 | | #include <utility> |
9 | | |
10 | | #include <cmext/string_view> |
11 | | |
12 | | #include "cmStringAlgorithms.h" |
13 | | |
14 | | namespace { |
15 | | |
16 | | #if __cplusplus >= 201703L |
17 | | constexpr unsigned validateDiagnosticsSubtree(unsigned parent, unsigned index) |
18 | 0 | { |
19 | 0 | // Ensure that all diagnostics, starting from the specified index, have the |
20 | 0 | // specified parent as an ancestor. Return the first index that violates |
21 | 0 | // this condition. |
22 | 0 | while (index < cmDiagnostics::CategoryCount && |
23 | 0 | cmDiagnostics::CategoryInfo[index].Parent == parent) { |
24 | 0 | unsigned const child = index; |
25 | 0 | // For each diagnostic, 'consume' its children (if any). |
26 | 0 | index = validateDiagnosticsSubtree(child, ++index); |
27 | 0 | } |
28 | 0 | return index; |
29 | 0 | } |
30 | | |
31 | | static_assert(validateDiagnosticsSubtree(cmDiagnostics::CMD_NONE, 1) == |
32 | | cmDiagnostics::CategoryCount, |
33 | | "Diagnostics are not properly ordered" |
34 | | " (hint: LHS is the index of the first misordered diagnostic)"); |
35 | | #endif |
36 | | |
37 | | cm::optional<cmDiagnosticCategory> stringToCategory(cm::string_view input) |
38 | 0 | { |
39 | 0 | using Map = std::map<cm::string_view, cmDiagnosticCategory>; |
40 | 0 | static Map const mapping = { |
41 | 0 | #define CATEGORY_MAP(C) { #C ""_s, cmDiagnostics::C }, |
42 | 0 | CM_FOR_EACH_DIAGNOSTIC_CATEGORY(CATEGORY_MAP) |
43 | 0 | #undef CATEGORY_MAP |
44 | 0 | }; |
45 | |
|
46 | 0 | assert(!input.empty()); |
47 | 0 | if (input.size() >= 4 && cmHasLiteralPrefix(input, "CMD_")) { |
48 | 0 | auto const i = mapping.find(input); |
49 | 0 | if (i != mapping.end()) { |
50 | 0 | return i->second; |
51 | 0 | } |
52 | 0 | } |
53 | | |
54 | 0 | return cm::nullopt; |
55 | 0 | } |
56 | | } |
57 | | |
58 | | #if __cplusplus < 201703L |
59 | | // Prior to C++17, the compiler is unhappy if this member doesn't have explicit |
60 | | // storage... and clang-tidy is unhappy if it does. |
61 | | // NOLINTNEXTLINE(*-redundant-declaration) |
62 | | constexpr cmDiagnostics::DiagnosticCategoryInformation |
63 | | cmDiagnostics::CategoryInfo[cmDiagnostics::CategoryCount]; |
64 | | #endif |
65 | | |
66 | | cm::string_view cmDiagnostics::GetActionString(DiagnosticAction action) |
67 | 0 | { |
68 | 0 | switch (action) { |
69 | 0 | case Ignore: |
70 | 0 | return "IGNORE"_s; |
71 | 0 | case Warn: |
72 | 0 | return "WARN"_s; |
73 | 0 | case SendError: |
74 | 0 | return "SEND_ERROR"_s; |
75 | 0 | case FatalError: |
76 | 0 | return "FATAL_ERROR"_s; |
77 | 0 | default: |
78 | 0 | return {}; |
79 | 0 | } |
80 | 0 | } |
81 | | |
82 | | cm::string_view cmDiagnostics::GetCategoryString(DiagnosticCategory category) |
83 | 28 | { |
84 | 28 | static cm::string_view const names[CategoryCount] = { |
85 | 28 | {}, // CMD_NONE |
86 | 588 | #define CATEGORY_NAME(C) #C ""_s, |
87 | 196 | CM_FOR_EACH_DIAGNOSTIC_CATEGORY(CATEGORY_NAME) |
88 | 28 | #undef CATEGORY_MAP |
89 | 28 | }; |
90 | | |
91 | 28 | if (category < CategoryCount) { |
92 | 28 | return names[category]; |
93 | 28 | } |
94 | 0 | return {}; |
95 | 28 | } |
96 | | |
97 | | cm::optional<cmDiagnosticAction> cmDiagnostics::GetDiagnosticAction( |
98 | | cm::string_view name) |
99 | 0 | { |
100 | 0 | if (name == "IGNORE"_s) { |
101 | 0 | return DiagnosticAction::Ignore; |
102 | 0 | } |
103 | 0 | if (name == "WARN"_s) { |
104 | 0 | return DiagnosticAction::Warn; |
105 | 0 | } |
106 | 0 | if (name == "SEND_ERROR"_s) { |
107 | 0 | return DiagnosticAction::SendError; |
108 | 0 | } |
109 | 0 | if (name == "FATAL_ERROR"_s) { |
110 | 0 | return DiagnosticAction::FatalError; |
111 | 0 | } |
112 | | |
113 | 0 | return cm::nullopt; |
114 | 0 | } |
115 | | |
116 | | cm::optional<cmDiagnosticCategory> cmDiagnostics::GetDiagnosticCategory( |
117 | | cm::string_view name) |
118 | 0 | { |
119 | 0 | return stringToCategory(name); |
120 | 0 | } |