]> git.armaanb.net Git - gen-shell.git/blobdiff - src/libshared/src/Color.cpp
removed libshared dependency
[gen-shell.git] / src / libshared / src / Color.cpp
diff --git a/src/libshared/src/Color.cpp b/src/libshared/src/Color.cpp
deleted file mode 100644 (file)
index 0673d81..0000000
+++ /dev/null
@@ -1,682 +0,0 @@
-////////////////////////////////////////////////////////////////////////////////
-//
-// Copyright 2006 - 2017, Paul Beckingham, Federico Hernandez.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included
-// in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-// SOFTWARE.
-//
-// http://www.opensource.org/licenses/mit-license.php
-//
-////////////////////////////////////////////////////////////////////////////////
-
-#include <cmake.h>
-#include <Color.h>
-#include <sstream>
-#include <vector>
-#include <cstdlib>
-#include <shared.h>
-#include <format.h>
-
-// uint to string lookup table for Color::_colorize()
-// _colorize() gets called _a lot_, having this lookup table is a cheap
-// performance optimization.
-const char *colorstring[] = {
-    "0",   "1",   "2",   "3",   "4",   "5",   "6",   "7",   "8",   "9",
-   "10",  "11",  "12",  "13",  "14",  "15",  "16",  "17",  "18",  "19",
-   "20",  "21",  "22",  "23",  "24",  "25",  "26",  "27",  "28",  "29",
-   "30",  "31",  "32",  "33",  "34",  "35",  "36",  "37",  "38",  "39",
-   "40",  "41",  "42",  "43",  "44",  "45",  "46",  "47",  "48",  "49",
-   "50",  "51",  "52",  "53",  "54",  "55",  "56",  "57",  "58",  "59",
-   "60",  "61",  "62",  "63",  "64",  "65",  "66",  "67",  "68",  "69",
-   "70",  "71",  "72",  "73",  "74",  "75",  "76",  "77",  "78",  "79",
-   "80",  "81",  "82",  "83",  "84",  "85",  "86",  "87",  "88",  "89",
-   "90",  "91",  "92",  "93",  "94",  "95",  "96",  "97",  "98",  "99",
-  "100", "101", "102", "103", "104", "105", "106", "107", "108", "109",
-  "110", "111", "112", "113", "114", "115", "116", "117", "118", "119",
-  "120", "121", "122", "123", "124", "125", "126", "127", "128", "129",
-  "130", "131", "132", "133", "134", "135", "136", "137", "138", "139",
-  "140", "141", "142", "143", "144", "145", "146", "147", "148", "149",
-  "150", "151", "152", "153", "154", "155", "156", "157", "158", "159",
-  "160", "161", "162", "163", "164", "165", "166", "167", "168", "169",
-  "170", "171", "172", "173", "174", "175", "176", "177", "178", "179",
-  "180", "181", "182", "183", "184", "185", "186", "187", "188", "189",
-  "190", "191", "192", "193", "194", "195", "196", "197", "198", "199",
-  "200", "201", "202", "203", "204", "205", "206", "207", "208", "209",
-  "210", "211", "212", "213", "214", "215", "216", "217", "218", "219",
-  "220", "221", "222", "223", "224", "225", "226", "227", "228", "229",
-  "230", "231", "232", "233", "234", "235", "236", "237", "238", "239",
-  "240", "241", "242", "243", "244", "245", "246", "247", "248", "249",
-  "250", "251", "252", "253", "254", "255"
-};
-
-////////////////////////////////////////////////////////////////////////////////
-static struct
-{
-  Color::color_id id;
-  std::string english_name;
-  int index;                    // offset red=3 (therefore fg=33, bg=43)
-} allColors[] =
-{
-  // Color.h enum    English     Index
-  { Color::nocolor,  "none",     0},
-  { Color::black,    "black",    1}, // fg 29+0  bg 39+0
-  { Color::red,      "red",      2},
-  { Color::green,    "green",    3},
-  { Color::yellow,   "yellow",   4},
-  { Color::blue,     "blue",     5},
-  { Color::magenta,  "magenta",  6},
-  { Color::cyan,     "cyan",     7},
-  { Color::white,    "white",    8},
-
-};
-
-#define NUM_COLORS (sizeof (allColors) / sizeof (allColors[0]))
-
-////////////////////////////////////////////////////////////////////////////////
-Color::Color ()
-: _value (0)
-{
-}
-
-////////////////////////////////////////////////////////////////////////////////
-Color::Color (const Color& other)
-{
-  _value = other._value;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-Color::Color (unsigned int c)
-: _value (0)
-{
-  if (!(c & _COLOR_HASFG)) _value &= ~_COLOR_FG;
-  if (!(c & _COLOR_HASBG)) _value &= ~_COLOR_BG;
-
-  _value = c & (_COLOR_256 | _COLOR_HASBG | _COLOR_HASFG |_COLOR_UNDERLINE |
-                _COLOR_INVERSE | _COLOR_BOLD | _COLOR_BRIGHT | _COLOR_BG |
-                _COLOR_FG);
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// Supports the following constructs:
-//   [bright] [color] [on color] [bright] [underline]
-//
-// Where [color] is one of:
-//   black
-//   red
-//   ...
-//   grayN  0 <= N <= 23       fg 38;5;232 + N              bg 48;5;232 + N
-//   greyN  0 <= N <= 23       fg 38;5;232 + N              bg 48;5;232 + N
-//   colorN 0 <= N <= 255      fg 38;5;N                    bg 48;5;N
-//   rgbRGB 0 <= R,G,B <= 5    fg 38;5;16 + R*36 + G*6 + B  bg 48;5;16 + R*36 + G*6 + B
-Color::Color (const std::string& spec)
-: _value (0)
-{
-  // Split spec into words.
-  auto words = split (spec, ' ');
-
-  // Construct the color as two separate colors, then blend them later.  This
-  // make it possible to declare a color such as "color1 on black", and have
-  // the upgrade work properly.
-  unsigned int fg_value = 0;
-  unsigned int bg_value = 0;
-
-  bool bg = false;
-  int index;
-  for (auto& word : words)
-  {
-    word = lowerCase (trim (word));
-
-         if (word == "bold")      fg_value |= _COLOR_BOLD;
-    else if (word == "bright")    bg_value |= _COLOR_BRIGHT;
-    else if (word == "underline") fg_value |= _COLOR_UNDERLINE;
-    else if (word == "inverse")   fg_value |= _COLOR_INVERSE;
-    else if (word == "on")        bg = true;
-
-    // X where X is one of black, red, blue ...
-    else if ((index = find (word)) != -1)
-    {
-      if (index)
-      {
-        if (bg)
-        {
-          bg_value |= _COLOR_HASBG;
-          bg_value |= index << 8;
-        }
-        else
-        {
-          fg_value |= _COLOR_HASFG;
-          fg_value |= index;
-        }
-      }
-    }
-
-    // greyN/grayN, where 0 <= N <= 23.
-    else if (! word.compare (0, 4, "grey", 4) ||
-             ! word.compare (0, 4, "gray", 4))
-    {
-      index = strtol (word.substr (4).c_str (), nullptr, 10);
-      if (index < 0 || index > 23)
-        throw format ("The color '{1}' is not recognized.", word);
-
-      if (bg)
-      {
-        bg_value |= _COLOR_HASBG;
-        bg_value |= (index + 232) << 8;
-        bg_value |= _COLOR_256;
-      }
-      else
-      {
-        fg_value |= _COLOR_HASFG;
-        fg_value |= index + 232;
-        fg_value |= _COLOR_256;
-      }
-    }
-
-    // rgbRGB, where 0 <= R,G,B <= 5.
-    else if (! word.compare (0, 3, "rgb", 3))
-    {
-      index = strtol (word.substr (3).c_str (), nullptr, 10);
-      if (word.length () != 6 ||
-          index < 0 || index > 555)
-        throw format ("The color '{1}' is not recognized.", word);
-
-      int r = strtol (word.substr (3, 1).c_str (), nullptr, 10);
-      int g = strtol (word.substr (4, 1).c_str (), nullptr, 10);
-      int b = strtol (word.substr (5, 1).c_str (), nullptr, 10);
-      if (r < 0 || r > 5 ||
-          g < 0 || g > 5 ||
-          b < 0 || b > 5)
-        throw format ("The color '{1}' is not recognized.", word);
-
-      index = 16 + r*36 + g*6 + b;
-
-      if (bg)
-      {
-        bg_value |= _COLOR_HASBG;
-        bg_value |= index << 8;
-        bg_value |= _COLOR_256;
-      }
-      else
-      {
-        fg_value |= _COLOR_HASFG;
-        fg_value |= index;
-        fg_value |= _COLOR_256;
-      }
-    }
-
-    // colorN, where 0 <= N <= 255.
-    else if (! word.compare (0, 5, "color", 5))
-    {
-      index = strtol (word.substr (5).c_str (), nullptr, 10);
-      if (index < 0 || index > 255)
-        throw format ("The color '{1}' is not recognized.", word);
-
-      upgrade ();
-
-      if (bg)
-      {
-        bg_value |= _COLOR_HASBG;
-        bg_value |= index << 8;
-        bg_value |= _COLOR_256;
-      }
-      else
-      {
-        fg_value |= _COLOR_HASFG;
-        fg_value |= index;
-        fg_value |= _COLOR_256;
-      }
-    }
-    else if (word != "")
-      throw format ("The color '{1}' is not recognized.", word);
-  }
-
-  // Now combine the fg and bg into a single color.
-  _value = fg_value;
-  blend (Color (bg_value));
-}
-
-////////////////////////////////////////////////////////////////////////////////
-Color::Color (color_id fg)
-: _value (0)
-{
-  if (fg != Color::nocolor)
-  {
-    _value |= _COLOR_HASFG;
-    _value |= fg;
-  }
-}
-
-////////////////////////////////////////////////////////////////////////////////
-Color::Color (color_id fg, color_id bg, bool underline, bool bold, bool bright)
-: _value (0)
-{
-  _value |= ((underline ? 1 : 0) << 18)
-         |  ((bold      ? 1 : 0) << 17)
-         |  ((bright    ? 1 : 0) << 16);
-
-  if (bg != Color::nocolor)
-  {
-    _value |= _COLOR_HASBG;
-    _value |= (bg << 8);
-  }
-
-  if (fg != Color::nocolor)
-  {
-    _value |= _COLOR_HASFG;
-    _value |= fg;
-  }
-}
-
-////////////////////////////////////////////////////////////////////////////////
-Color::operator std::string () const
-{
-  std::string description;
-  if (_value & _COLOR_BOLD) description += "bold";
-
-  if (_value & _COLOR_UNDERLINE)
-    description += std::string (description.length () ? " " : "") + "underline";
-
-  if (_value & _COLOR_INVERSE)
-    description += std::string (description.length () ? " " : "") + "inverse";
-
-  if (_value & _COLOR_HASFG)
-    description += std::string (description.length () ? " " : "") + fg ();
-
-  if (_value & _COLOR_HASBG)
-  {
-    description += std::string (description.length () ? " " : "") + "on";
-
-    if (_value & _COLOR_BRIGHT)
-      description += std::string (description.length () ? " " : "") + "bright";
-
-    description += " " + bg ();
-  }
-
-  return description;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-Color::operator int () const
-{
-  return (int) _value;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// If 'other' has styles that are compatible, merge them into this.  Colors in
-// other take precedence.
-void Color::blend (const Color& other)
-{
-  if (!other.nontrivial ())
-    return;
-
-  Color c (other);
-  _value |= (c._value & _COLOR_UNDERLINE);    // Always inherit underline.
-  _value |= (c._value & _COLOR_INVERSE);      // Always inherit inverse.
-
-  // 16 <-- 16.
-  if (!(_value   & _COLOR_256) &&
-      !(c._value & _COLOR_256))
-  {
-    _value |= (c._value & _COLOR_BOLD);       // Inherit bold.
-    _value |= (c._value & _COLOR_BRIGHT);     // Inherit bright.
-
-    if (c._value & _COLOR_HASFG)
-    {
-      _value |= _COLOR_HASFG;                 // There is now a color.
-      _value &= ~_COLOR_FG;                   // Remove previous color.
-      _value |= (c._value & _COLOR_FG);       // Apply other color.
-    }
-
-    if (c._value & _COLOR_HASBG)
-    {
-      _value |= _COLOR_HASBG;                 // There is now a color.
-      _value &= ~_COLOR_BG;                   // Remove previous color.
-      _value |= (c._value & _COLOR_BG);       // Apply other color.
-    }
-
-    return;
-  }
-  else
-  {
-    // Upgrade either color, if necessary.
-    if (!(_value   & _COLOR_256)) upgrade ();
-    if (!(c._value & _COLOR_256)) c.upgrade ();
-
-    // 256 <-- 256.
-    if (c._value & _COLOR_HASFG)
-    {
-      _value |= _COLOR_HASFG;                  // There is now a color.
-      _value &= ~_COLOR_FG;                    // Remove previous color.
-      _value |= (c._value & _COLOR_FG);        // Apply other color.
-    }
-
-    if (c._value & _COLOR_HASBG)
-    {
-      _value |= _COLOR_HASBG;                  // There is now a color.
-      _value &= ~_COLOR_BG;                    // Remove previous color.
-      _value |= (c._value & _COLOR_BG);        // Apply other color.
-    }
-  }
-}
-
-////////////////////////////////////////////////////////////////////////////////
-void Color::upgrade ()
-{
-  if (!(_value & _COLOR_256))
-  {
-    if (_value & _COLOR_HASFG)
-    {
-      bool bold = _value & _COLOR_BOLD;
-      unsigned int fg = _value & _COLOR_FG;
-      _value &= ~_COLOR_FG;
-      _value &= ~_COLOR_BOLD;
-      _value |= (bold ? fg + 7 : fg - 1);
-    }
-
-    if (_value & _COLOR_HASBG)
-    {
-      bool bright = _value & _COLOR_BRIGHT;
-      unsigned int bg = (_value & _COLOR_BG) >> 8;
-      _value &= ~_COLOR_BG;
-      _value &= ~_COLOR_BRIGHT;
-      _value |= (bright ? bg + 7 : bg - 1) << 8;
-    }
-
-    _value |= _COLOR_256;
-  }
-}
-
-////////////////////////////////////////////////////////////////////////////////
-std::string Color::colorize (const std::string& input) const
-{
-  std::string result;
-  _colorize (result, input);
-  return result;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// Sample color codes:
-//   red                  \033[31m
-//   bold red             \033[91m
-//   underline red        \033[4;31m
-//   bold underline red   \033[1;4;31m
-//
-//   on red               \033[41m
-//   on bright red        \033[101m
-//
-//   256 fg               \033[38;5;Nm
-//   256 bg               \033[48;5;Nm
-void Color::_colorize (std::string &result, const std::string& input) const
-{
-  if (!nontrivial ())
-  {
-    result += input;
-    return;
-  }
-
-  int count = 0;
-
-  // 256 color
-  if (_value & _COLOR_256)
-  {
-    if (_value & _COLOR_UNDERLINE)
-      result += "\033[4m";
-
-    if (_value & _COLOR_INVERSE)
-      result += "\033[7m";
-
-    if (_value & _COLOR_HASFG)
-    {
-      result += "\033[38;5;";
-      result += colorstring[(_value & _COLOR_FG)];
-      result += 'm';
-    }
-
-    if (_value & _COLOR_HASBG)
-    {
-      result += "\033[48;5;";
-      result += colorstring[((_value & _COLOR_BG) >> 8)];
-      result += 'm';
-    }
-
-    result += input;
-    result += "\033[0m";
-  }
-
-  // 16 color
-  else
-  {
-    result += "\033[";
-
-    if (_value & _COLOR_BOLD)
-    {
-      if (count++) result += ';';
-      result += '1';
-    }
-
-    if (_value & _COLOR_UNDERLINE)
-    {
-      if (count++) result += ';';
-      result += '4';
-    }
-
-    if (_value & _COLOR_INVERSE)
-    {
-      if (count++) result += ';';
-      result += '7';
-    }
-
-    if (_value & _COLOR_HASFG)
-    {
-      if (count++) result += ';';
-      result += colorstring[(29 + (_value & _COLOR_FG))];
-    }
-
-    if (_value & _COLOR_HASBG)
-    {
-      if (count++) result += ';';
-      result += colorstring[((_value & _COLOR_BRIGHT ? 99 : 39) + ((_value & _COLOR_BG) >> 8))];
-    }
-
-    result += 'm';
-    result += input;
-    result += "\033[0m";
-  }
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// Remove color codes from a string.
-std::string Color::strip (const std::string& input)
-{
-  int length = input.length ();
-  bool inside = false;
-  std::string output;
-  for (int i = 0; i < length; ++i)
-  {
-    if (inside)
-    {
-      if (input[i] == 'm')
-        inside = false;
-    }
-    else
-    {
-      if (input[i] == 033)
-        inside = true;
-      else
-        output += input[i];
-    }
-  }
-
-  return output;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-std::string Color::colorize (const std::string& input, const std::string& spec)
-{
-  Color c (spec);
-  return c.colorize (input);
-}
-
-////////////////////////////////////////////////////////////////////////////////
-std::string Color::code () const
-{
-  if (! nontrivial ())
-    return "";
-
-  std::string result;
-
-  // 256 color
-  if (_value & _COLOR_256)
-  {
-    if (_value & _COLOR_UNDERLINE)
-      result += "\033[4m";
-
-    if (_value & _COLOR_INVERSE)
-      result += "\033[7m";
-
-    if (_value & _COLOR_HASFG)
-    {
-      result += "\033[38;5;";
-      result += colorstring[(_value & _COLOR_FG)];
-      result += 'm';
-    }
-
-    if (_value & _COLOR_HASBG)
-    {
-      result += "\033[48;5;";
-      result += colorstring[((_value & _COLOR_BG) >> 8)];
-      result += 'm';
-    }
-  }
-
-  // 16 color
-  else
-  {
-    int count = 0;
-    result += "\033[";
-
-    if (_value & _COLOR_BOLD)
-    {
-      if (count++) result += ';';
-      result += '1';
-    }
-
-    if (_value & _COLOR_UNDERLINE)
-    {
-      if (count++) result += ';';
-      result += '4';
-    }
-
-    if (_value & _COLOR_INVERSE)
-    {
-      if (count++) result += ';';
-      result += '7';
-    }
-
-    if (_value & _COLOR_HASFG)
-    {
-      if (count++) result += ';';
-      result += colorstring[(29 + (_value & _COLOR_FG))];
-    }
-
-    if (_value & _COLOR_HASBG)
-    {
-      if (count++) result += ';';
-      result += colorstring[((_value & _COLOR_BRIGHT ? 99 : 39) + ((_value & _COLOR_BG) >> 8))];
-    }
-
-    result += 'm';
-  }
-
-  return result;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-std::string Color::end () const
-{
-  if (nontrivial ())
-    return "\033[0m";
-
-  return "";
-}
-
-////////////////////////////////////////////////////////////////////////////////
-bool Color::nontrivial () const
-{
-  return _value != 0 ? true : false;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-int Color::find (const std::string& input)
-{
-  for (unsigned int i = 0; i < NUM_COLORS; ++i)
-    if (allColors[i].english_name == input)
-      return (int) i;
-
-  return -1;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-std::string Color::fg () const
-{
-  int index = _value & _COLOR_FG;
-
-  if (_value & _COLOR_256)
-  {
-    if (_value & _COLOR_HASFG)
-    {
-      std::stringstream s;
-      s << "color" << (_value & _COLOR_FG);
-      return s.str ();
-    }
-  }
-  else
-  {
-    for (unsigned int i = 0; i < NUM_COLORS; ++i)
-      if (allColors[i].index == index)
-        return allColors[i].english_name;
-  }
-
-  return "";
-}
-
-////////////////////////////////////////////////////////////////////////////////
-std::string Color::bg () const
-{
-  int index = (_value & _COLOR_BG) >> 8;
-
-  if (_value & _COLOR_256)
-  {
-    if (_value & _COLOR_HASBG)
-    {
-      std::stringstream s;
-      s << "color" << ((_value & _COLOR_BG) >> 8);
-      return s.str ();
-    }
-  }
-  else
-  {
-    for (unsigned int i = 0; i < NUM_COLORS; ++i)
-      if (allColors[i].index == index)
-        return allColors[i].english_name;
-  }
-
-  return "";
-}
-
-////////////////////////////////////////////////////////////////////////////////