Parcourir la source

[quickfix] search unicode

isundil il y a 9 ans
Parent
commit
d0c16a5714
8 fichiers modifiés avec 60 ajouts et 39 suppressions
  1. 1 0
      include/curseOutput.hh
  2. 3 0
      include/params.hh
  3. 4 4
      include/searchPattern.hh
  4. 20 6
      src/curseOutput.cpp
  5. 1 1
      src/linearHistory.cpp
  6. 0 1
      src/main.cpp
  7. 2 4
      src/params.cpp
  8. 29 23
      src/searchPattern.cpp

+ 1 - 0
include/curseOutput.hh

@@ -127,6 +127,7 @@ class CurseOutput
          * Write a message on the last line, using color
         **/
         void writeBottomLine(const std::string &currentBuffer, short color) const;
+        void writeBottomLine(const std::wstring &currentBuffer, short color) const;
 
         /**
          * unfold all item's parents

+ 3 - 0
include/params.hh

@@ -43,6 +43,7 @@ class Params: public AParams
          * can be file stream (-f), stringstream ( -- INPUT), or std::cin (none)
         **/
         std::basic_istream<char> &getInput() const;
+
         /**
          * false if invalid argument is passed
         **/
@@ -53,11 +54,13 @@ class Params: public AParams
          * @param program name
         **/
         virtual void usage() const noexcept;
+
         /**
          * print version number
          * @param program name
         **/
         virtual void version() const noexcept;
+
         /**
          * get argv[0]
         **/

+ 4 - 4
include/searchPattern.hh

@@ -7,7 +7,7 @@ class JSonElement;
 class SearchPattern
 {
     public:
-        SearchPattern(const char *);
+        SearchPattern(const wchar_t *);
         ~SearchPattern();
 
         bool isEmpty() const;
@@ -16,12 +16,12 @@ class SearchPattern
         /**
          * Comparison function, for std::search use
         **/
-        bool operator()(char a, char b);
+        bool operator()(wchar_t a, wchar_t b);
 
     private:
-        void evalFlags(const char *);
+        void evalFlags(const wchar_t *);
 
-        std::string pattern;
+        std::wstring pattern;
         short flags;
         short typeFlag;
 

+ 20 - 6
src/curseOutput.cpp

@@ -614,7 +614,7 @@ void CurseOutput::unfold(const JSonElement *item)
 
 const SearchPattern *CurseOutput::inputSearch()
 {
-    std::string buffer;
+    std::wstring buffer;
     bool abort = false;
 
     curs_set(true);
@@ -623,12 +623,12 @@ const SearchPattern *CurseOutput::inputSearch()
     {
         int c;
 
-        writeBottomLine('/' +buffer, OutputFlag::SPECIAL_SEARCH);
+        writeBottomLine(L'/' +buffer, OutputFlag::SPECIAL_SEARCH);
         refresh();
-        c = getch();
-        if (c == '\n')
+        c = getwchar();
+        if (c == L'\r')
             break;
-        else if (c == '\b' || c == 127)
+        else if (c == L'\b' || c == 127)
         {
             if (!buffer.empty())
                 buffer.pop_back();
@@ -647,7 +647,8 @@ const SearchPattern *CurseOutput::inputSearch()
 void CurseOutput::writeBottomLine(const std::string &buffer, short color) const
 {
     const std::pair<unsigned int, unsigned int> screenSize = getScreenSize();
-    size_t bufsize = buffer.size();
+    const size_t bufsize = buffer.size();
+
     if (params.colorEnabled())
         attron(COLOR_PAIR(color));
     mvprintw(screenSize.second -1, 0, "%s%*c", buffer.c_str(), screenSize.first - bufsize, ' ');
@@ -656,6 +657,19 @@ void CurseOutput::writeBottomLine(const std::string &buffer, short color) const
         attroff(COLOR_PAIR(color));
 }
 
+void CurseOutput::writeBottomLine(const std::wstring &buffer, short color) const
+{
+    const std::pair<unsigned int, unsigned int> screenSize = getScreenSize();
+    const size_t bufsize = buffer.size();
+
+    if (params.colorEnabled())
+        attron(COLOR_PAIR(color));
+    mvprintw(screenSize.second -1, 0, "%S%*c", buffer.c_str(), screenSize.first - bufsize, ' ');
+    move(screenSize.second -1, bufsize);
+    if (params.colorEnabled())
+        attroff(COLOR_PAIR(color));
+}
+
 void CurseOutput::init()
 {
     if (!isatty(fileno(stdin)) || !isatty(fileno(stdout)))

+ 1 - 1
src/linearHistory.cpp

@@ -23,7 +23,7 @@ void LinearHistory::put(char item)
         line++;
         willReset = false;
     }
-    if (item == '\n')
+    if (item == L'\n' || item == L'\r')
         willReset = true;
     else
         WrappedBuffer<char, ERROR_HISTORY_LEN>::put(item);

+ 0 - 1
src/main.cpp

@@ -20,7 +20,6 @@ void displayException(const Params *params, const std::string &type, const JsonE
 
 void run(Params *params)
 {
-
     StreamConsumer stream(StreamConsumer(params->getInput()));
     stream.withConfig(params);
     CurseOutput *out;

+ 2 - 4
src/params.cpp

@@ -13,7 +13,7 @@
 
 #include "config.h"
 
-Params::Params(char **av) :progName(*av), strict(true)
+Params::Params(char **av): input(nullptr), progName(*av), strict(true)
 {
     av++;
     while (*av)
@@ -36,9 +36,7 @@ bool Params::read()
         if (!input)
         {
             if (tmp == "--")
-            {
                 input = new std::stringstream();
-            }
             else if (tmp == "-W")
                 strict = false;
             else if (tmp == "--ascii")
@@ -115,7 +113,7 @@ void Params::usage() const noexcept
     << "if not INPUT nor FILENAME, use standard input" << std::endl << std::endl
 
     << "  FILENAME\t\tread input from filename instead of stdin" << std::endl
-    << "  INPUT\t\tuse this as input instead of stdin" << std::endl
+    << "  INPUT\t\t\tuse this as input instead of stdin" << std::endl
     << "  -W \t\t\tconsider continuing on non-blocking errors" << std::endl
     << "  --ascii\t\tignore unicode values" << std::endl
     << "  --color[=MODE]\tcolorize output, MODE can be never or always (default when ommited)" << std::endl

+ 29 - 23
src/searchPattern.cpp

@@ -5,25 +5,25 @@
 #include "jsonObjectEntry.hh"
 #include "jsonPrimitive.hh"
 
-SearchPattern::SearchPattern(const char *input): flags(0)
+SearchPattern::SearchPattern(const wchar_t *input): flags(0)
 {
     size_t pos = 0;
     bool escaped = false;
-    std::stringstream ss;
+    std::wstringstream ss;
 
     for (pos =0; input[pos]; ++pos)
     {
         if (escaped)
         {
-            if (input[pos] == '/')
+            if (input[pos] == L'/')
                 ss.put(input[pos]);
             else
-                ss.put('\\').put(input[pos]);
+                ss.put(L'\\').put(input[pos]);
             escaped = false;
         }
-        else if (input[pos] == '\\')
+        else if (input[pos] == L'\\')
             escaped = true;
-        else if (input[pos] == '/')
+        else if (input[pos] == L'/')
         {
             pattern = ss.str();
             evalFlags(&input[pos +1]);
@@ -38,26 +38,26 @@ SearchPattern::SearchPattern(const char *input): flags(0)
 SearchPattern::~SearchPattern()
 { }
 
-void SearchPattern::evalFlags(const char *s)
+void SearchPattern::evalFlags(const wchar_t *s)
 {
     while (*s)
     {
-        if (*s == 'i')
+        if (*s == L'i')
         {
             flags |= SearchPattern::FLAG_CASE;
             std::transform(pattern.begin(), pattern.end(), pattern.begin(), ::tolower);
         }
-        else if (*s == 'b')
+        else if (*s == L'b')
             typeFlag = SearchPattern::TYPE_BOOL;
-        else if (*s == 'n')
+        else if (*s == L'n')
             typeFlag = SearchPattern::TYPE_NUMBER;
-        else if (*s == 's')
+        else if (*s == L's')
             typeFlag = SearchPattern::TYPE_STRING;
-        else if (*s == 'o')
+        else if (*s == L'o')
             typeFlag = SearchPattern::TYPE_OBJKEY;
-        else if (*s == 'w')
+        else if (*s == L'w')
             flags |= SearchPattern::FLAG_WHOLEWORD;
-        else if (*s == 'f')
+        else if (*s == L'f')
             flags |= SearchPattern::FLAG_WHOLESTR;
         s++;
     }
@@ -66,10 +66,10 @@ void SearchPattern::evalFlags(const char *s)
 bool SearchPattern::isEmpty() const
 { return pattern.empty(); }
 
-bool SearchPattern::operator()(char a, char b)
+bool SearchPattern::operator()(wchar_t a, wchar_t b)
 {
-    if (a == '\t')
-        a = ' ';
+    if (a == L'\t')
+        a = L' ';
     if (flags & SearchPattern::FLAG_CASE)
         return std::tolower(a) == b;
     return a == b;
@@ -77,6 +77,12 @@ bool SearchPattern::operator()(char a, char b)
 
 bool SearchPattern::match(const std::string &str, const JSonElement *type) const
 {
+    // Init str
+    const size_t size = str.size();
+    wchar_t tmpBuf[size];
+    mbstowcs(&tmpBuf[0], str.c_str(), size);
+    std::wstring wstr = std::wstring(tmpBuf, size);
+
     if (typeFlag)
     {
         if (typeFlag == SearchPattern::TYPE_BOOL && !(dynamic_cast<const JSonPrimitive<bool> *>(type)))
@@ -91,15 +97,15 @@ bool SearchPattern::match(const std::string &str, const JSonElement *type) const
                 !(dynamic_cast<const JSonPrimitive<long long> *>(type)))
             return false;
     }
-    if ((flags & FLAG_WHOLESTR && str.length() != pattern.length())
-            || pattern.length() > str.length())
+    if ((flags & FLAG_WHOLESTR && wstr.length() != pattern.length())
+            || pattern.length() > wstr.length())
         return false;
-    if (flags & FLAG_WHOLEWORD && str.length() > pattern.length())
+    if (flags & FLAG_WHOLEWORD && wstr.length() > pattern.length())
     {
-        std::string pattern = ' ' +this->pattern +' ';
-            return std::search(str.begin(), str.end(), pattern.begin(), pattern.end(), *this) != str.end();
+        std::wstring pattern = L' ' +this->pattern +L' ';
+        return std::search(wstr.begin(), wstr.end(), pattern.begin(), pattern.end(), *this) != wstr.end();
     }
-    return std::search(str.begin(), str.end(), pattern.begin(), pattern.end(), *this) != str.end();
+    return std::search(wstr.begin(), wstr.end(), pattern.begin(), pattern.end(), *this) != wstr.end();
 }
 
 const short SearchPattern::FLAG_CASE        = 1;