Files
CMake/Source/CursesDialog/cmCursesColor.cxx
Brad King ea47c154e5 Make case-dependent operations locale-independent
Use ASCII-only ctype operations provided by KWSys String.
These match the "C" locale in which `cmake` has long run.
2026-02-11 11:55:50 -05:00

80 lines
1.9 KiB
C++

/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file LICENSE.rst or https://cmake.org/licensing for details. */
#include "cmCursesColor.h"
#include <cstdlib>
#include <cstring>
#include <unordered_map>
#include <utility>
#include "cmsys/String.h"
#include "cmCursesStandardIncludes.h"
bool cmCursesColor::HasColors()
{
#ifdef HAVE_CURSES_USE_DEFAULT_COLORS
return has_colors();
#else
return false;
#endif
}
void cmCursesColor::InitColors()
{
#ifdef HAVE_CURSES_USE_DEFAULT_COLORS
if (HasColors()) {
start_color();
use_default_colors();
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] == '=') {
char const n = cmsysString_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);
}