Improve handling of mbyte chars in UTF8Char::IsSpace

* Switch UTF8Char's IsSpace, IsAlNum, ToLower functions to use
  system-wide BUnicodeChar service routines;
* Switch TermView::CharClassifier to use UTF8Char instead of
  raw char* string ponter. That reduces count of conversions
  and simplify code;

  Fixes #7423.
This commit is contained in:
Siarzhuk Zharski
2013-03-17 16:45:49 +01:00
parent 53953e3e68
commit c7047b8fd2
4 changed files with 37 additions and 20 deletions
+3 -3
View File
@@ -421,7 +421,7 @@ BasicTerminalBuffer::FindWord(const TermPos& pos,
x--;
// get the char type at the given position
int type = classifier->Classify(line->cells[x].character.bytes);
int type = classifier->Classify(line->cells[x].character);
// check whether we are supposed to find words only
if (type != CHAR_TYPE_WORD_CHAR && !findNonWords)
@@ -444,7 +444,7 @@ BasicTerminalBuffer::FindWord(const TermPos& pos,
if (x > 0 && IS_WIDTH(line->cells[x - 1].attributes))
x--;
if (classifier->Classify(line->cells[x].character.bytes) != type)
if (classifier->Classify(line->cells[x].character) != type)
break;
start.SetTo(x, y);
@@ -467,7 +467,7 @@ BasicTerminalBuffer::FindWord(const TermPos& pos,
break;
}
if (classifier->Classify(line->cells[x].character.bytes) != type)
if (classifier->Classify(line->cells[x].character) != type)
break;
x += IS_WIDTH(line->cells[x].attributes) ? 2 : 1;
+17 -10
View File
@@ -24,6 +24,7 @@
#include <algorithm>
#include <new>
#include <vector>
#include <Alert.h>
#include <Application.h>
@@ -144,28 +145,34 @@ restrict_value(const Type& value, const Type& min, const Type& max)
class TermView::CharClassifier : public TerminalCharClassifier {
public:
CharClassifier(const char* specialWordChars)
:
fSpecialWordChars(specialWordChars)
{
const char* p = specialWordChars;
while (p != NULL && *p) {
int count = UTF8Char::ByteCount(*p);
if (count <= 0 || count > 4)
break;
fSpecialWordChars.push_back(UTF8Char(p, count));
p += count;
}
}
virtual int Classify(const char* character)
virtual int Classify(const UTF8Char& character)
{
// TODO: Deal correctly with non-ASCII chars.
char c = *character;
if (UTF8Char::ByteCount(c) > 1)
if (character.IsSpace())
return CHAR_TYPE_SPACE;
if (character.IsAlNum())
return CHAR_TYPE_WORD_CHAR;
if (isspace(c))
return CHAR_TYPE_SPACE;
if (isalnum(c) || strchr(fSpecialWordChars, c) != NULL)
if (std::find(fSpecialWordChars.begin(), fSpecialWordChars.end(),
character) != fSpecialWordChars.end())
return CHAR_TYPE_WORD_CHAR;
return CHAR_TYPE_WORD_DELIMITER;
}
private:
const char* fSpecialWordChars;
std::vector<UTF8Char> fSpecialWordChars;
};
+3 -1
View File
@@ -13,11 +13,13 @@ enum {
};
class UTF8Char;
class TerminalCharClassifier {
public:
virtual ~TerminalCharClassifier();
virtual int Classify(const char* character) = 0;
virtual int Classify(const UTF8Char& character) = 0;
};
+14 -6
View File
@@ -8,6 +8,8 @@
#include <ctype.h>
#include <string.h>
#include <UnicodeChar.h>
struct UTF8Char {
char bytes[4];
@@ -63,17 +65,23 @@ struct UTF8Char {
bool IsSpace() const
{
// TODO: Support multi-byte chars!
return ByteCount() == 1 ? isspace(bytes[0]) : false;
return BUnicodeChar::IsSpace(BUnicodeChar::FromUTF8(bytes));
}
bool IsAlNum() const
{
return BUnicodeChar::IsAlNum(BUnicodeChar::FromUTF8(bytes));
}
UTF8Char ToLower() const
{
// TODO: Support multi-byte chars!
if (ByteCount() > 1)
return *this;
uint32 c = BUnicodeChar::ToLower(BUnicodeChar::FromUTF8(bytes));
return UTF8Char((char)tolower(bytes[0]));
UTF8Char character;
char* utf8 = character.bytes;
BUnicodeChar::ToUTF8(c, &utf8);
return character;
}
bool operator==(const UTF8Char& other) const