|
@@ -50,6 +50,24 @@ enum class ATTR : std::int8_t {
|
|
|
INVERSE = 7
|
|
|
};
|
|
|
|
|
|
+// std::int32_t
|
|
|
+
|
|
|
+constexpr long strhash(const char *txt) {
|
|
|
+ long result = 0;
|
|
|
+
|
|
|
+ for (int x = 0; x < 3; ++x) {
|
|
|
+ // char c = txt[x] - 'A';
|
|
|
+ result = (result << 8) | txt[x];
|
|
|
+ }
|
|
|
+
|
|
|
+ return result;
|
|
|
+};
|
|
|
+
|
|
|
+#define A_BOLD 0x01
|
|
|
+#define A_BLINK 0x02
|
|
|
+#define A_INVERSE 0x04
|
|
|
+#define A_RESET 0x10
|
|
|
+
|
|
|
/**
|
|
|
* @class ANSIColor
|
|
|
* This holds foreground, background and ANSI-BBS attribute
|
|
@@ -65,17 +83,10 @@ class ANSIColor {
|
|
|
COLOR fg;
|
|
|
/** Background color */
|
|
|
COLOR bg;
|
|
|
- // Track attributes (ATTR)
|
|
|
- /** reset flag / always send color and attributes */
|
|
|
- unsigned int reset : 1;
|
|
|
- /** bold / bright flag */
|
|
|
- unsigned int bold : 1;
|
|
|
- /** blink slow blinking text */
|
|
|
- unsigned int blink : 1;
|
|
|
- /** inverse */
|
|
|
- unsigned int inverse : 1;
|
|
|
-
|
|
|
-public:
|
|
|
+
|
|
|
+ int attr;
|
|
|
+
|
|
|
+ public:
|
|
|
ANSIColor();
|
|
|
ANSIColor(ATTR a);
|
|
|
ANSIColor(COLOR f);
|
|
@@ -85,6 +96,104 @@ public:
|
|
|
ANSIColor(COLOR f, COLOR b, ATTR a);
|
|
|
ANSIColor(COLOR f, COLOR b, ATTR a1, ATTR a2);
|
|
|
ANSIColor(std::initializer_list<int> il);
|
|
|
+
|
|
|
+ constexpr ANSIColor(const char *text)
|
|
|
+ : fg(COLOR::WHITE),
|
|
|
+ bg(COLOR::BLACK),
|
|
|
+ attr(0) {
|
|
|
+ const char *cp = text;
|
|
|
+ bool use_on = false;
|
|
|
+
|
|
|
+ while (*cp != 0) {
|
|
|
+ long key = strhash(cp);
|
|
|
+
|
|
|
+ switch (key) {
|
|
|
+ case strhash("BRI"):
|
|
|
+ attr |= A_BOLD;
|
|
|
+ break;
|
|
|
+ case strhash("BOL"):
|
|
|
+ attr |= A_BOLD;
|
|
|
+ break;
|
|
|
+ case strhash("BLI"):
|
|
|
+ attr |= A_BLINK;
|
|
|
+ break;
|
|
|
+ case strhash("INV"):
|
|
|
+ attr |= A_INVERSE;
|
|
|
+ break;
|
|
|
+ case strhash("RES"):
|
|
|
+ attr |= A_RESET;
|
|
|
+ break;
|
|
|
+ case strhash("ON "):
|
|
|
+ use_on = true;
|
|
|
+ break;
|
|
|
+
|
|
|
+ case strhash("BLU"):
|
|
|
+ if (use_on)
|
|
|
+ bg = COLOR::BLUE;
|
|
|
+ else
|
|
|
+ bg = COLOR::BLUE;
|
|
|
+
|
|
|
+ break;
|
|
|
+ case strhash("RED"):
|
|
|
+ if (use_on)
|
|
|
+ bg = COLOR::RED;
|
|
|
+ else
|
|
|
+ fg = COLOR::RED;
|
|
|
+ break;
|
|
|
+ case strhash("GRE"):
|
|
|
+ if (use_on)
|
|
|
+ bg = COLOR::GREEN;
|
|
|
+ else
|
|
|
+ fg = COLOR::GREEN;
|
|
|
+ break;
|
|
|
+ case strhash("YEL"):
|
|
|
+ if (use_on)
|
|
|
+ bg = COLOR::YELLOW;
|
|
|
+ else {
|
|
|
+ fg = COLOR::YELLOW;
|
|
|
+ attr |= A_BOLD;
|
|
|
+ }
|
|
|
+ // if (use_on) throw error!
|
|
|
+ break;
|
|
|
+ case strhash("BRO"):
|
|
|
+ if (use_on)
|
|
|
+ bg = COLOR::BROWN;
|
|
|
+ else
|
|
|
+ fg = COLOR::BROWN;
|
|
|
+ break;
|
|
|
+ case strhash("CYA"):
|
|
|
+ if (use_on)
|
|
|
+ bg = COLOR::CYAN;
|
|
|
+ else
|
|
|
+ fg = COLOR::CYAN;
|
|
|
+ break;
|
|
|
+ case strhash("MAG"):
|
|
|
+ if (use_on)
|
|
|
+ bg = COLOR::MAGENTA;
|
|
|
+ else
|
|
|
+ fg = COLOR::MAGENTA;
|
|
|
+ break;
|
|
|
+ case strhash("BLA"):
|
|
|
+ if (use_on)
|
|
|
+ bg = COLOR::BLACK;
|
|
|
+ else
|
|
|
+ fg = COLOR::BLACK;
|
|
|
+ break;
|
|
|
+ case strhash("WHI"):
|
|
|
+ if (use_on)
|
|
|
+ bg = COLOR::WHITE;
|
|
|
+ else
|
|
|
+ fg = COLOR::WHITE;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ // skip to the space character
|
|
|
+ while ((*cp != ' ') && (*cp != 0)) ++cp;
|
|
|
+ // skip past the space character
|
|
|
+ while (*cp == ' ') ++cp;
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
/*
|
|
|
ANSIColor(int c1);
|
|
|
ANSIColor(int c1, int c2);
|
|
@@ -107,12 +216,211 @@ public:
|
|
|
* @return COLOR
|
|
|
*/
|
|
|
COLOR getBg() { return bg; };
|
|
|
- void attr(ATTR a);
|
|
|
+ void setAttr(ATTR a);
|
|
|
|
|
|
std::string output(void) const;
|
|
|
std::string operator()(void) const;
|
|
|
};
|
|
|
|
|
|
+#ifdef NON_WORKING
|
|
|
+#include <vector>
|
|
|
+
|
|
|
+constexpr std::vector<int> from_text(const char *text) {
|
|
|
+ std::vector<int> vi;
|
|
|
+
|
|
|
+ const char *cp = text;
|
|
|
+ bool use_on = false;
|
|
|
+
|
|
|
+ while (*cp != 0) {
|
|
|
+ int key = strhash(cp);
|
|
|
+
|
|
|
+ switch (key) {
|
|
|
+ case strhash("BRI"):
|
|
|
+ vi.push_back(1);
|
|
|
+ break;
|
|
|
+ case strhash("BOL"):
|
|
|
+ vi.push_back(1);
|
|
|
+ break;
|
|
|
+ case strhash("BLI"):
|
|
|
+ vi.push_back(5);
|
|
|
+ break;
|
|
|
+ case strhash("INV"):
|
|
|
+ vi.push_back(7);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case strhash("ON "):
|
|
|
+ use_on = true;
|
|
|
+ break;
|
|
|
+
|
|
|
+ case strhash("BLU"):
|
|
|
+ if (use_on)
|
|
|
+ ac.setBg(COLOR::BLUE);
|
|
|
+ else
|
|
|
+ ac.setFg(COLOR::BLUE);
|
|
|
+
|
|
|
+ break;
|
|
|
+ case strhash("RED"):
|
|
|
+ if (use_on)
|
|
|
+ ac.setBg(COLOR::RED);
|
|
|
+ else
|
|
|
+ ac.setFg(COLOR::RED);
|
|
|
+ break;
|
|
|
+ case strhash("GRE"):
|
|
|
+ if (use_on)
|
|
|
+ ac.setBg(COLOR::GREEN);
|
|
|
+ else
|
|
|
+ ac.setFg(COLOR::GREEN);
|
|
|
+ break;
|
|
|
+ case strhash("YEL"):
|
|
|
+ // if (use_on) throw error!
|
|
|
+ ac.setFg(COLOR::YELLOW);
|
|
|
+ ac.Attr(ATTR::BOLD);
|
|
|
+ break;
|
|
|
+ case strhash("BRO"):
|
|
|
+ if (use_on)
|
|
|
+ ac.setBg(COLOR::BROWN);
|
|
|
+ else
|
|
|
+ ac.setFg(COLOR::BROWN);
|
|
|
+ break;
|
|
|
+ case strhash("CYA"):
|
|
|
+ if (use_on)
|
|
|
+ ac.setBg(COLOR::CYAN);
|
|
|
+ else
|
|
|
+ ac.setFg(COLOR::CYAN);
|
|
|
+ break;
|
|
|
+ case strhash("MAG"):
|
|
|
+ if (use_on)
|
|
|
+ ac.setBg(COLOR::MAGENTA);
|
|
|
+ else
|
|
|
+ ac.setFg(COLOR::MAGENTA);
|
|
|
+ break;
|
|
|
+ case strhash("BLA"):
|
|
|
+ if (use_on)
|
|
|
+ ac.setBg(COLOR::BLACK);
|
|
|
+ else
|
|
|
+ ac.setFg(COLOR::BLACK);
|
|
|
+ break;
|
|
|
+ case strhash("WHI"):
|
|
|
+ if (use_on)
|
|
|
+ ac.setBg(COLOR::WHITE);
|
|
|
+ else
|
|
|
+ ac.setFg(COLOR::WHITE);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ // skip to the space character
|
|
|
+ while ((*cp != ' ') && (*cp != 0)) ++cp;
|
|
|
+ // skip past the space character
|
|
|
+ while (*cp == ' ') ++cp;
|
|
|
+ }
|
|
|
+ return vi;
|
|
|
+}
|
|
|
+#endif
|
|
|
+
|
|
|
+/*
|
|
|
+Maybe make char, char, char (fg, bg, attr) and store those from
|
|
|
+the constexpr.
|
|
|
+
|
|
|
+This "works", in that it does construct an ANSIColor from text.
|
|
|
+
|
|
|
+However, it isn't stored as an ANSIColor, but calls the function
|
|
|
+at run-time. (I was hoping for an efficient way to construct
|
|
|
+ANSIColor from a string.)
|
|
|
+
|
|
|
+Maybe a template that constructs it from a initializer_list?
|
|
|
+ */
|
|
|
+
|
|
|
+constexpr ANSIColor ac_from_text(const char *text) {
|
|
|
+ ANSIColor ac(nullptr);
|
|
|
+
|
|
|
+ const char *cp = text;
|
|
|
+ bool use_on = false;
|
|
|
+
|
|
|
+ while (*cp != 0) {
|
|
|
+ int key = strhash(cp);
|
|
|
+
|
|
|
+ switch (key) {
|
|
|
+ case strhash("BRI"):
|
|
|
+ ac.Attr(ATTR::BRIGHT);
|
|
|
+ break;
|
|
|
+ case strhash("BOL"):
|
|
|
+ ac.Attr(ATTR::BOLD);
|
|
|
+ break;
|
|
|
+ case strhash("BLI"):
|
|
|
+ ac.Attr(ATTR::BLINK);
|
|
|
+ break;
|
|
|
+ case strhash("INV"):
|
|
|
+ ac.Attr(ATTR::INVERSE);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case strhash("ON "):
|
|
|
+ use_on = true;
|
|
|
+ break;
|
|
|
+
|
|
|
+ case strhash("BLU"):
|
|
|
+ if (use_on)
|
|
|
+ ac.setBg(COLOR::BLUE);
|
|
|
+ else
|
|
|
+ ac.setFg(COLOR::BLUE);
|
|
|
+
|
|
|
+ break;
|
|
|
+ case strhash("RED"):
|
|
|
+ if (use_on)
|
|
|
+ ac.setBg(COLOR::RED);
|
|
|
+ else
|
|
|
+ ac.setFg(COLOR::RED);
|
|
|
+ break;
|
|
|
+ case strhash("GRE"):
|
|
|
+ if (use_on)
|
|
|
+ ac.setBg(COLOR::GREEN);
|
|
|
+ else
|
|
|
+ ac.setFg(COLOR::GREEN);
|
|
|
+ break;
|
|
|
+ case strhash("YEL"):
|
|
|
+ // if (use_on) throw error!
|
|
|
+ ac.setFg(COLOR::YELLOW);
|
|
|
+ ac.Attr(ATTR::BOLD);
|
|
|
+ break;
|
|
|
+ case strhash("BRO"):
|
|
|
+ if (use_on)
|
|
|
+ ac.setBg(COLOR::BROWN);
|
|
|
+ else
|
|
|
+ ac.setFg(COLOR::BROWN);
|
|
|
+ break;
|
|
|
+ case strhash("CYA"):
|
|
|
+ if (use_on)
|
|
|
+ ac.setBg(COLOR::CYAN);
|
|
|
+ else
|
|
|
+ ac.setFg(COLOR::CYAN);
|
|
|
+ break;
|
|
|
+ case strhash("MAG"):
|
|
|
+ if (use_on)
|
|
|
+ ac.setBg(COLOR::MAGENTA);
|
|
|
+ else
|
|
|
+ ac.setFg(COLOR::MAGENTA);
|
|
|
+ break;
|
|
|
+ case strhash("BLA"):
|
|
|
+ if (use_on)
|
|
|
+ ac.setBg(COLOR::BLACK);
|
|
|
+ else
|
|
|
+ ac.setFg(COLOR::BLACK);
|
|
|
+ break;
|
|
|
+ case strhash("WHI"):
|
|
|
+ if (use_on)
|
|
|
+ ac.setBg(COLOR::WHITE);
|
|
|
+ else
|
|
|
+ ac.setFg(COLOR::WHITE);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ // skip to the space character
|
|
|
+ while ((*cp != ' ') && (*cp != 0)) ++cp;
|
|
|
+ // skip past the space character
|
|
|
+ while (*cp == ' ') ++cp;
|
|
|
+ }
|
|
|
+ return ac;
|
|
|
+};
|
|
|
+
|
|
|
extern ANSIColor reset;
|
|
|
|
|
|
#endif
|