Skip to content
Snippets Groups Projects
Select Git revision
  • master default protected
  • loss
  • producer
3 results

util.cpp

Blame
  • util.cpp 5.76 KiB
    #include "util.hpp"
    #include "utf8.hpp"
    #include <ctime>
    #include <algorithm>
    #include "upper2lower"
    
    int util::printedLength(std::string_view s)
    {
      return splitAsUtf8(s).size();
    }
    
    std::string_view util::getFilenameFromPath(std::string_view s)
    {
      int indexOfSlash = s.find_last_of('/');
      return {s.data()+indexOfSlash+1, s.size()-1-indexOfSlash};
    }
    
    bool util::isSeparator(utf8char c)
    {
      return c == ' ' || isIllegal(c);
    }
    
    bool util::isIllegal(utf8char c)
    {
      return c == '\n' || c == '\t';
    }
    
    std::vector<std::string> util::split(std::string_view remaining, char delimiter)
    {
      std::vector<std::string> result;
    
      for (auto firstDelimiterIndex = remaining.find_first_of(delimiter); firstDelimiterIndex != std::string_view::npos; firstDelimiterIndex = remaining.find_first_of(delimiter))
      {
        if (remaining[0] != delimiter)
          result.emplace_back(remaining.data(), firstDelimiterIndex);
        remaining = std::string_view(remaining.data()+firstDelimiterIndex+1, remaining.size()-1-firstDelimiterIndex);
      }
    
      if (remaining.size() > 0)
        result.emplace_back(remaining);
    
      return result;
    }
    
    util::utf8string util::splitAsUtf8(std::string_view s)
    {
      utf8string result;
      const char * beginPtr = s.data();
      const char * currentPtr = beginPtr;
      const char * endPtr = s.data()+s.size();
    
      while (currentPtr < endPtr)
      {
        try {utf8::next(currentPtr, endPtr);}
        catch (std::exception &)
        {
          break;
        }
        if (currentPtr - beginPtr > 4 || currentPtr - beginPtr == 0)
          myThrow(fmt::format("Invalid utf8 character at index {}", beginPtr-s.data()));
    
        utf8char c;
    
        for (int i = 0; i < currentPtr - beginPtr; i++)
          c[i] = beginPtr[i];
    
        beginPtr = currentPtr;
        result.push_back(c);
      }
    
      return result;
    }
    
    std::string util::shrink(const std::string & s, int printedSize)
    {
      static const std::string filler = "…";
    
      if (printedLength(s) <= printedSize)
        return s;
    
      auto splited = splitAsUtf8(s);
    
      std::string result;
      std::string begin, end;
      int nbLoop = 0;
    
      while (printedLength(begin)+printedLength(end)+printedLength(filler) <= printedSize)
      {
        result = begin + filler + end;
    
        if (nbLoop % 2)
          end = fmt::format("{}{}", splited[splited.size()-1-(nbLoop/2)], end);
        else
          begin = fmt::format("{}{}", begin, splited[nbLoop/2]);
    
        ++nbLoop;
      }
    
      return result;
    }
    
    void util::warning(std::string_view message, const std::experimental::source_location & location)
    {
      fmt::print(stderr, "WARNING ({}) : {}\n", location, message);
    }
    
    void util::error(std::string_view message, const std::experimental::source_location & location)
    {
      fmt::print(stderr, "ERROR ({}) : {}\n", location, message);
      exit(1);
    }
    
    void util::error(const std::exception & e, const std::experimental::source_location & location)
    {
      error(e.what(), location);
    }
    
    void util::myThrow(std::string_view message, const std::experimental::source_location & location)
    {
      throw std::invalid_argument(fmt::format("from ({}) {}", location, message));
    }
    
    std::string util::int2HumanStr(int number)
    {
      std::string nb = std::to_string(number);
      std::string result;
    
      for (unsigned int i = 0; i < nb.size(); i++)
      {
        result.push_back(nb[i]);
        if (((nb.size()-i-1) % 3 == 0) && i < nb.size()-1)
          result.push_back(' ');
      }
    
      return result;
    }
    
    bool util::doIfNameMatch(const std::regex & reg, std::string_view name, const std::function<void(const std::smatch &)> & f)
    {
      std::smatch sm;
      std::string sname(name);
      std::regex_match(sname, sm, reg);
    
      if (sm.empty())
        return false;
    
      f(sm);
    
      return true;
    }
    
    std::string util::strip(const std::string & s)
    {
      std::string striped;
    
      if (s.empty())
        return striped;
    
      std::size_t first = 0;
      while (first < s.size() and (s[first] == ' ' or s[first] == '\t'))
        ++first;
    
      std::size_t last = s.size()-1;
      while (last > first and (s[last] == ' ' or s[last] == '\t' or s[last] == '\n'))
        --last;
    
      return std::string(s.begin()+first, s.begin()+last+1);
    }
    
    std::vector<std::filesystem::path> util::findFilesByExtension(std::filesystem::path directory, std::string extension)
    {
      std::vector<std::filesystem::path> files;
    
      for (auto entry : std::filesystem::directory_iterator(directory))
        if (entry.is_regular_file())
        {
          auto path = entry.path();
          if (path.extension() == extension)
            files.push_back(path);
        }
    
      return files;
    }
    
    std::string util::getTime()
    {
      std::time_t rawtime;
      char buffer[80];
    
      std::time(&rawtime);
    
      std::strftime(buffer, sizeof(buffer), "%H:%M:%S", std::localtime(&rawtime));
      return std::string(buffer);
    }
    
    bool util::choiceWithProbability(float probability)
    {
      int maxVal = 100000;
      int threshold = maxVal * probability;
    
      return (std::rand() % maxVal) < threshold;
    }
    
    bool util::isUppercase(utf8char c)
    {
      return upper2lower.count(c);
    }
    
    std::string util::lower(const std::string & s)
    {
      auto splited = util::splitAsUtf8(s);
      lower(splited);
    
      return fmt::format("{}", splited);
    }
    
    void util::lower(utf8string & s)
    {
      for (auto & c : s)
      {
        auto it = upper2lower.find(c);
        if (it != upper2lower.end())
          c = it->second;
      }
    }
    
    util::utf8string util::lower(const utf8string & s)
    {
      auto result = s;
      lower(result);
    
      return result;
    }
    
    void util::lower(utf8char & c)
    {
      auto it = upper2lower.find(c);
      if (it != upper2lower.end())
        c = it->second;
    }
    
    std::string util::upper(const std::string & s)
    {
      auto splited = util::splitAsUtf8(s);
      upper(splited);
    
      return fmt::format("{}", splited);
    }
    
    void util::upper(utf8string & s)
    {
      for (auto & c : s)
      {
        auto it = lower2upper.find(c);
        if (it != lower2upper.end())
          c = it->second;
      }
    }
    
    util::utf8string util::upper(const utf8string & s)
    {
      auto result = s;
      upper(result);
    
      return result;
    }
    
    void util::upper(utf8char & c)
    {
      auto it = lower2upper.find(c);
      if (it != lower2upper.end())
        c = it->second;
    }