cmCursesColor.cxx 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
  2. file Copyright.txt or https://cmake.org/licensing for details. */
  3. #include "cmCursesColor.h"
  4. #include <cctype>
  5. #include <cstdlib>
  6. #include <cstring>
  7. #include <unordered_map>
  8. #include <utility>
  9. #include "cmCursesStandardIncludes.h"
  10. bool cmCursesColor::HasColors()
  11. {
  12. #ifdef HAVE_CURSES_USE_DEFAULT_COLORS
  13. return has_colors();
  14. #else
  15. return false;
  16. #endif
  17. }
  18. void cmCursesColor::InitColors()
  19. {
  20. #ifdef HAVE_CURSES_USE_DEFAULT_COLORS
  21. if (HasColors()) {
  22. start_color();
  23. use_default_colors();
  24. init_pair(BoolOff, GetColor('N', COLOR_RED), -1);
  25. init_pair(BoolOn, GetColor('Y', COLOR_GREEN), -1);
  26. init_pair(String, GetColor('S', COLOR_CYAN), -1);
  27. init_pair(Path, GetColor('P', COLOR_YELLOW), -1);
  28. init_pair(Choice, GetColor('C', COLOR_MAGENTA), -1);
  29. }
  30. #endif
  31. }
  32. short cmCursesColor::GetColor(char id, short fallback)
  33. {
  34. static bool initialized = false;
  35. static std::unordered_map<char, short> env;
  36. if (!initialized) {
  37. if (auto* v = getenv("CCMAKE_COLORS")) {
  38. while (v[0] && v[1] && v[1] == '=') {
  39. auto const n = std::toupper(*v);
  40. char buffer[12];
  41. memset(buffer, 0, sizeof(buffer));
  42. if (auto* const e = strchr(v, ':')) {
  43. if (static_cast<size_t>(e - v) > sizeof(buffer)) {
  44. break;
  45. }
  46. strncpy(buffer, v + 2, static_cast<size_t>(e - v - 2));
  47. v = e + 1;
  48. } else {
  49. auto const l = strlen(v);
  50. if (l > sizeof(buffer)) {
  51. break;
  52. }
  53. strncpy(buffer, v + 2, l - 2);
  54. v += l;
  55. }
  56. auto const c = atoi(buffer);
  57. if (c && c < COLORS) {
  58. env.emplace(n, static_cast<short>(c));
  59. }
  60. }
  61. }
  62. initialized = true;
  63. }
  64. auto const iter = env.find(id);
  65. return (iter == env.end() ? fallback : iter->second);
  66. }