|
|
@@ -2,6 +2,12 @@
|
|
|
file Copyright.txt or https://cmake.org/licensing for details. */
|
|
|
#include "cmCursesColor.h"
|
|
|
|
|
|
+#include <cctype>
|
|
|
+#include <cstdlib>
|
|
|
+#include <cstring>
|
|
|
+#include <unordered_map>
|
|
|
+#include <utility>
|
|
|
+
|
|
|
#include "cmCursesStandardIncludes.h"
|
|
|
|
|
|
bool cmCursesColor::HasColors()
|
|
|
@@ -19,11 +25,54 @@ void cmCursesColor::InitColors()
|
|
|
if (HasColors()) {
|
|
|
start_color();
|
|
|
use_default_colors();
|
|
|
- init_pair(cmCursesColor::BoolOff, COLOR_RED, -1);
|
|
|
- init_pair(cmCursesColor::BoolOn, COLOR_GREEN, -1);
|
|
|
- init_pair(cmCursesColor::String, COLOR_BLUE, -1);
|
|
|
- init_pair(cmCursesColor::Path, COLOR_YELLOW, -1);
|
|
|
- init_pair(cmCursesColor::Options, COLOR_MAGENTA, -1);
|
|
|
+ init_pair(BoolOff, GetColor('N', COLOR_RED), -1);
|
|
|
+ init_pair(BoolOn, GetColor('Y', COLOR_GREEN), -1);
|
|
|
+ init_pair(String, GetColor('S', COLOR_CYAN), -1);
|
|
|
+ init_pair(Path, GetColor('P', COLOR_YELLOW), -1);
|
|
|
+ init_pair(Choice, GetColor('C', COLOR_MAGENTA), -1);
|
|
|
}
|
|
|
#endif
|
|
|
}
|
|
|
+
|
|
|
+short cmCursesColor::GetColor(char id, short fallback)
|
|
|
+{
|
|
|
+ static bool initialized = false;
|
|
|
+ static std::unordered_map<char, short> env;
|
|
|
+
|
|
|
+ if (!initialized) {
|
|
|
+ if (auto* v = getenv("CCMAKE_COLORS")) {
|
|
|
+ while (v[0] && v[1] && v[1] == '=') {
|
|
|
+ auto const n = std::toupper(*v);
|
|
|
+
|
|
|
+ char buffer[12];
|
|
|
+ memset(buffer, 0, sizeof(buffer));
|
|
|
+
|
|
|
+ if (auto* const e = strchr(v, ':')) {
|
|
|
+ if (static_cast<size_t>(e - v) > sizeof(buffer)) {
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ strncpy(buffer, v + 2, static_cast<size_t>(e - v - 2));
|
|
|
+ v = e + 1;
|
|
|
+ } else {
|
|
|
+ auto const l = strlen(v);
|
|
|
+ if (l > sizeof(buffer)) {
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ strncpy(buffer, v + 2, l - 2);
|
|
|
+ v += l;
|
|
|
+ }
|
|
|
+
|
|
|
+ auto const c = atoi(buffer);
|
|
|
+ if (c && c < COLORS) {
|
|
|
+ env.emplace(n, static_cast<short>(c));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ initialized = true;
|
|
|
+ }
|
|
|
+
|
|
|
+ auto const iter = env.find(id);
|
|
|
+ return (iter == env.end() ? fallback : iter->second);
|
|
|
+}
|