2010-08-21 23:59:56 +00:00
|
|
|
// Scintilla source code edit control
|
|
|
|
/** @file CharacterSet.h
|
|
|
|
** Encapsulates a set of characters. Used to test if a character is within a set.
|
|
|
|
**/
|
|
|
|
// Copyright 2007 by Neil Hodgson <neilh@scintilla.org>
|
|
|
|
// The License.txt file describes the conditions under which this software may be distributed.
|
|
|
|
|
|
|
|
#ifndef CHARACTERSET_H
|
|
|
|
#define CHARACTERSET_H
|
|
|
|
|
|
|
|
#ifdef SCI_NAMESPACE
|
|
|
|
namespace Scintilla {
|
|
|
|
#endif
|
|
|
|
|
|
|
|
class CharacterSet {
|
|
|
|
int size;
|
|
|
|
bool valueAfter;
|
|
|
|
bool *bset;
|
|
|
|
public:
|
|
|
|
enum setBase {
|
|
|
|
setNone=0,
|
|
|
|
setLower=1,
|
|
|
|
setUpper=2,
|
|
|
|
setDigits=4,
|
|
|
|
setAlpha=setLower|setUpper,
|
|
|
|
setAlphaNum=setAlpha|setDigits
|
|
|
|
};
|
|
|
|
CharacterSet(setBase base=setNone, const char *initialSet="", int size_=0x80, bool valueAfter_=false) {
|
|
|
|
size = size_;
|
|
|
|
valueAfter = valueAfter_;
|
|
|
|
bset = new bool[size];
|
|
|
|
for (int i=0; i < size; i++) {
|
|
|
|
bset[i] = false;
|
|
|
|
}
|
|
|
|
AddString(initialSet);
|
|
|
|
if (base & setLower)
|
|
|
|
AddString("abcdefghijklmnopqrstuvwxyz");
|
|
|
|
if (base & setUpper)
|
|
|
|
AddString("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
|
|
|
|
if (base & setDigits)
|
|
|
|
AddString("0123456789");
|
|
|
|
}
|
2013-08-28 00:44:27 +00:00
|
|
|
CharacterSet(const CharacterSet &other) {
|
|
|
|
size = other.size;
|
|
|
|
valueAfter = other.valueAfter;
|
|
|
|
bset = new bool[size];
|
|
|
|
for (int i=0; i < size; i++) {
|
|
|
|
bset[i] = other.bset[i];
|
|
|
|
}
|
|
|
|
}
|
2010-08-21 23:59:56 +00:00
|
|
|
~CharacterSet() {
|
|
|
|
delete []bset;
|
|
|
|
bset = 0;
|
|
|
|
size = 0;
|
|
|
|
}
|
2013-08-28 00:44:27 +00:00
|
|
|
CharacterSet &operator=(const CharacterSet &other) {
|
|
|
|
if (this != &other) {
|
|
|
|
bool *bsetNew = new bool[other.size];
|
|
|
|
for (int i=0; i < other.size; i++) {
|
|
|
|
bsetNew[i] = other.bset[i];
|
|
|
|
}
|
|
|
|
delete []bset;
|
|
|
|
size = other.size;
|
|
|
|
valueAfter = other.valueAfter;
|
|
|
|
bset = bsetNew;
|
|
|
|
}
|
|
|
|
return *this;
|
|
|
|
}
|
2010-08-21 23:59:56 +00:00
|
|
|
void Add(int val) {
|
|
|
|
assert(val >= 0);
|
|
|
|
assert(val < size);
|
|
|
|
bset[val] = true;
|
|
|
|
}
|
2011-03-22 00:16:49 +00:00
|
|
|
void AddString(const char *setToAdd) {
|
|
|
|
for (const char *cp=setToAdd; *cp; cp++) {
|
2010-08-21 23:59:56 +00:00
|
|
|
int val = static_cast<unsigned char>(*cp);
|
|
|
|
assert(val >= 0);
|
|
|
|
assert(val < size);
|
|
|
|
bset[val] = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
bool Contains(int val) const {
|
|
|
|
assert(val >= 0);
|
|
|
|
if (val < 0) return false;
|
|
|
|
return (val < size) ? bset[val] : valueAfter;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
// Functions for classifying characters
|
|
|
|
|
|
|
|
inline bool IsASpace(int ch) {
|
|
|
|
return (ch == ' ') || ((ch >= 0x09) && (ch <= 0x0d));
|
|
|
|
}
|
|
|
|
|
|
|
|
inline bool IsASpaceOrTab(int ch) {
|
|
|
|
return (ch == ' ') || (ch == '\t');
|
|
|
|
}
|
|
|
|
|
|
|
|
inline bool IsADigit(int ch) {
|
|
|
|
return (ch >= '0') && (ch <= '9');
|
|
|
|
}
|
|
|
|
|
|
|
|
inline bool IsADigit(int ch, int base) {
|
|
|
|
if (base <= 10) {
|
|
|
|
return (ch >= '0') && (ch < '0' + base);
|
|
|
|
} else {
|
|
|
|
return ((ch >= '0') && (ch <= '9')) ||
|
|
|
|
((ch >= 'A') && (ch < 'A' + base - 10)) ||
|
|
|
|
((ch >= 'a') && (ch < 'a' + base - 10));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
inline bool IsASCII(int ch) {
|
2013-08-28 00:44:27 +00:00
|
|
|
return (ch >= 0) && (ch < 0x80);
|
|
|
|
}
|
|
|
|
|
|
|
|
inline bool IsLowerCase(int ch) {
|
|
|
|
return (ch >= 'a') && (ch <= 'z');
|
|
|
|
}
|
|
|
|
|
|
|
|
inline bool IsUpperCase(int ch) {
|
|
|
|
return (ch >= 'A') && (ch <= 'Z');
|
2010-08-21 23:59:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
inline bool IsAlphaNumeric(int ch) {
|
|
|
|
return
|
|
|
|
((ch >= '0') && (ch <= '9')) ||
|
|
|
|
((ch >= 'a') && (ch <= 'z')) ||
|
|
|
|
((ch >= 'A') && (ch <= 'Z'));
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Check if a character is a space.
|
|
|
|
* This is ASCII specific but is safe with chars >= 0x80.
|
|
|
|
*/
|
|
|
|
inline bool isspacechar(int ch) {
|
|
|
|
return (ch == ' ') || ((ch >= 0x09) && (ch <= 0x0d));
|
|
|
|
}
|
|
|
|
|
|
|
|
inline bool iswordchar(int ch) {
|
2013-08-28 00:44:27 +00:00
|
|
|
return IsAlphaNumeric(ch) || ch == '.' || ch == '_';
|
2010-08-21 23:59:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
inline bool iswordstart(int ch) {
|
2013-08-28 00:44:27 +00:00
|
|
|
return IsAlphaNumeric(ch) || ch == '_';
|
2010-08-21 23:59:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
inline bool isoperator(int ch) {
|
2013-08-28 00:44:27 +00:00
|
|
|
if (IsAlphaNumeric(ch))
|
2010-08-21 23:59:56 +00:00
|
|
|
return false;
|
|
|
|
if (ch == '%' || ch == '^' || ch == '&' || ch == '*' ||
|
|
|
|
ch == '(' || ch == ')' || ch == '-' || ch == '+' ||
|
|
|
|
ch == '=' || ch == '|' || ch == '{' || ch == '}' ||
|
|
|
|
ch == '[' || ch == ']' || ch == ':' || ch == ';' ||
|
|
|
|
ch == '<' || ch == '>' || ch == ',' || ch == '/' ||
|
|
|
|
ch == '?' || ch == '!' || ch == '.' || ch == '~')
|
|
|
|
return true;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Simple case functions for ASCII.
|
|
|
|
|
|
|
|
inline char MakeUpperCase(char ch) {
|
|
|
|
if (ch < 'a' || ch > 'z')
|
|
|
|
return ch;
|
|
|
|
else
|
|
|
|
return static_cast<char>(ch - 'a' + 'A');
|
|
|
|
}
|
|
|
|
|
|
|
|
int CompareCaseInsensitive(const char *a, const char *b);
|
|
|
|
int CompareNCaseInsensitive(const char *a, const char *b, size_t len);
|
|
|
|
|
|
|
|
#ifdef SCI_NAMESPACE
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#endif
|