AnsiTerminal.h 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. #ifndef LLDB_UTILITY_ANSITERMINAL_H
  2. #define LLDB_UTILITY_ANSITERMINAL_H
  3. //===---------------------AnsiTerminal.h ------------------------*- C++ -*-===//
  4. //
  5. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  6. // See https://llvm.org/LICENSE.txt for license information.
  7. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  8. //
  9. //===----------------------------------------------------------------------===//
  10. #define ANSI_FG_COLOR_BLACK 30
  11. #define ANSI_FG_COLOR_RED 31
  12. #define ANSI_FG_COLOR_GREEN 32
  13. #define ANSI_FG_COLOR_YELLOW 33
  14. #define ANSI_FG_COLOR_BLUE 34
  15. #define ANSI_FG_COLOR_PURPLE 35
  16. #define ANSI_FG_COLOR_CYAN 36
  17. #define ANSI_FG_COLOR_WHITE 37
  18. #define ANSI_BG_COLOR_BLACK 40
  19. #define ANSI_BG_COLOR_RED 41
  20. #define ANSI_BG_COLOR_GREEN 42
  21. #define ANSI_BG_COLOR_YELLOW 43
  22. #define ANSI_BG_COLOR_BLUE 44
  23. #define ANSI_BG_COLOR_PURPLE 45
  24. #define ANSI_BG_COLOR_CYAN 46
  25. #define ANSI_BG_COLOR_WHITE 47
  26. #define ANSI_SPECIAL_FRAMED 51
  27. #define ANSI_SPECIAL_ENCIRCLED 52
  28. #define ANSI_CTRL_NORMAL 0
  29. #define ANSI_CTRL_BOLD 1
  30. #define ANSI_CTRL_FAINT 2
  31. #define ANSI_CTRL_ITALIC 3
  32. #define ANSI_CTRL_UNDERLINE 4
  33. #define ANSI_CTRL_SLOW_BLINK 5
  34. #define ANSI_CTRL_FAST_BLINK 6
  35. #define ANSI_CTRL_IMAGE_NEGATIVE 7
  36. #define ANSI_CTRL_CONCEAL 8
  37. #define ANSI_CTRL_CROSSED_OUT 9
  38. #define ANSI_ESC_START "\033["
  39. #define ANSI_ESC_END "m"
  40. #define ANSI_STR(s) #s
  41. #define ANSI_DEF_STR(s) ANSI_STR(s)
  42. #define ANSI_ESCAPE1(s) ANSI_ESC_START ANSI_DEF_STR(s) ANSI_ESC_END
  43. #define ANSI_1_CTRL(ctrl1) "\033["##ctrl1 ANSI_ESC_END
  44. #define ANSI_2_CTRL(ctrl1, ctrl2) "\033["##ctrl1 ";"##ctrl2 ANSI_ESC_END
  45. #include "llvm/ADT/ArrayRef.h"
  46. #include "llvm/ADT/STLExtras.h"
  47. #include "llvm/ADT/StringRef.h"
  48. #include <string>
  49. namespace lldb_private {
  50. namespace ansi {
  51. inline std::string FormatAnsiTerminalCodes(llvm::StringRef format,
  52. bool do_color = true) {
  53. // Convert "${ansi.XXX}" tokens to ansi values or clear them if do_color is
  54. // false.
  55. static const struct {
  56. const char *name;
  57. const char *value;
  58. } g_color_tokens[] = {
  59. #define _TO_STR2(_val) #_val
  60. #define _TO_STR(_val) _TO_STR2(_val)
  61. {"fg.black}", ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_BLACK) ANSI_ESC_END},
  62. {"fg.red}", ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_RED) ANSI_ESC_END},
  63. {"fg.green}", ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_GREEN) ANSI_ESC_END},
  64. {"fg.yellow}", ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_YELLOW) ANSI_ESC_END},
  65. {"fg.blue}", ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_BLUE) ANSI_ESC_END},
  66. {"fg.purple}", ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_PURPLE) ANSI_ESC_END},
  67. {"fg.cyan}", ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_CYAN) ANSI_ESC_END},
  68. {"fg.white}", ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_WHITE) ANSI_ESC_END},
  69. {"bg.black}", ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_BLACK) ANSI_ESC_END},
  70. {"bg.red}", ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_RED) ANSI_ESC_END},
  71. {"bg.green}", ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_GREEN) ANSI_ESC_END},
  72. {"bg.yellow}", ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_YELLOW) ANSI_ESC_END},
  73. {"bg.blue}", ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_BLUE) ANSI_ESC_END},
  74. {"bg.purple}", ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_PURPLE) ANSI_ESC_END},
  75. {"bg.cyan}", ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_CYAN) ANSI_ESC_END},
  76. {"bg.white}", ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_WHITE) ANSI_ESC_END},
  77. {"normal}", ANSI_ESC_START _TO_STR(ANSI_CTRL_NORMAL) ANSI_ESC_END},
  78. {"bold}", ANSI_ESC_START _TO_STR(ANSI_CTRL_BOLD) ANSI_ESC_END},
  79. {"faint}", ANSI_ESC_START _TO_STR(ANSI_CTRL_FAINT) ANSI_ESC_END},
  80. {"italic}", ANSI_ESC_START _TO_STR(ANSI_CTRL_ITALIC) ANSI_ESC_END},
  81. {"underline}", ANSI_ESC_START _TO_STR(ANSI_CTRL_UNDERLINE) ANSI_ESC_END},
  82. {"slow-blink}",
  83. ANSI_ESC_START _TO_STR(ANSI_CTRL_SLOW_BLINK) ANSI_ESC_END},
  84. {"fast-blink}",
  85. ANSI_ESC_START _TO_STR(ANSI_CTRL_FAST_BLINK) ANSI_ESC_END},
  86. {"negative}",
  87. ANSI_ESC_START _TO_STR(ANSI_CTRL_IMAGE_NEGATIVE) ANSI_ESC_END},
  88. {"conceal}", ANSI_ESC_START _TO_STR(ANSI_CTRL_CONCEAL) ANSI_ESC_END},
  89. {"crossed-out}",
  90. ANSI_ESC_START _TO_STR(ANSI_CTRL_CROSSED_OUT) ANSI_ESC_END},
  91. #undef _TO_STR
  92. #undef _TO_STR2
  93. };
  94. auto codes = llvm::makeArrayRef(g_color_tokens);
  95. static const char tok_hdr[] = "${ansi.";
  96. std::string fmt;
  97. while (!format.empty()) {
  98. llvm::StringRef left, right;
  99. std::tie(left, right) = format.split(tok_hdr);
  100. fmt += left;
  101. if (left == format && right.empty()) {
  102. // The header was not found. Just exit.
  103. break;
  104. }
  105. bool found_code = false;
  106. for (const auto &code : codes) {
  107. if (!right.consume_front(code.name))
  108. continue;
  109. if (do_color)
  110. fmt.append(code.value);
  111. found_code = true;
  112. break;
  113. }
  114. format = right;
  115. // If we haven't found a valid replacement value, we just copy the string
  116. // to the result without any modifications.
  117. if (!found_code)
  118. fmt.append(tok_hdr);
  119. }
  120. return fmt;
  121. }
  122. }
  123. } // namespace lldb_private
  124. #endif