A Whole New World (clang-format edition)
I can show you the code Pretty, with proper whitespace Tell me, coder, now when did You last write readable code? I can open your eyes Make you see your bad indent Force you to respect the style The core devs agreed upon A whole new world A new fantastic code format A de facto standard With some sugar Enforced with clang-format A whole new world A dazzling style we all dreamed of And when we read it through It's crystal clear That now we're in a whole new world of code
This commit is contained in:
@ -28,11 +28,10 @@
|
||||
/*************************************************************************/
|
||||
|
||||
#include "regex.h"
|
||||
#include <wctype.h>
|
||||
#include <wchar.h>
|
||||
#include <wctype.h>
|
||||
|
||||
static int RegEx_hex2int(const CharType c)
|
||||
{
|
||||
static int RegEx_hex2int(const CharType c) {
|
||||
if ('0' <= c && c <= '9')
|
||||
return int(c - '0');
|
||||
else if ('a' <= c && c <= 'f')
|
||||
@ -45,7 +44,7 @@ static int RegEx_hex2int(const CharType c)
|
||||
struct RegExSearch {
|
||||
|
||||
Ref<RegExMatch> match;
|
||||
const CharType* str;
|
||||
const CharType *str;
|
||||
int end;
|
||||
int eof;
|
||||
|
||||
@ -63,7 +62,8 @@ struct RegExSearch {
|
||||
return str[p_pos];
|
||||
}
|
||||
|
||||
RegExSearch(Ref<RegExMatch>& p_match, int p_end, int p_lookahead) : match(p_match) {
|
||||
RegExSearch(Ref<RegExMatch> &p_match, int p_end, int p_lookahead)
|
||||
: match(p_match) {
|
||||
|
||||
str = p_match->string.c_str();
|
||||
end = p_end;
|
||||
@ -71,14 +71,13 @@ struct RegExSearch {
|
||||
complete = false;
|
||||
lookahead_pos.resize(p_lookahead);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
struct RegExNode {
|
||||
|
||||
RegExNode* next;
|
||||
RegExNode* previous;
|
||||
RegExNode* parent;
|
||||
RegExNode *next;
|
||||
RegExNode *previous;
|
||||
RegExNode *parent;
|
||||
bool quantifiable;
|
||||
int length;
|
||||
|
||||
@ -100,12 +99,12 @@ struct RegExNode {
|
||||
// For avoiding RTTI
|
||||
virtual bool is_look_behind() { return false; }
|
||||
|
||||
virtual int test(RegExSearch& s, int pos) const {
|
||||
virtual int test(RegExSearch &s, int pos) const {
|
||||
|
||||
return next ? next->test(s, pos) : -1;
|
||||
}
|
||||
|
||||
virtual int test_parent(RegExSearch& s, int pos) const {
|
||||
virtual int test_parent(RegExSearch &s, int pos) const {
|
||||
|
||||
if (next)
|
||||
pos = next->test(s, pos);
|
||||
@ -135,9 +134,7 @@ struct RegExNode {
|
||||
|
||||
if (parent)
|
||||
parent->increment_length(amount, subtract);
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
struct RegExNodeChar : public RegExNode {
|
||||
@ -151,7 +148,7 @@ struct RegExNodeChar : public RegExNode {
|
||||
ch = p_char;
|
||||
}
|
||||
|
||||
virtual int test(RegExSearch& s, int pos) const {
|
||||
virtual int test(RegExSearch &s, int pos) const {
|
||||
|
||||
if (s.end <= pos || 0 > pos || s.at(pos) != ch)
|
||||
return -1;
|
||||
@ -159,7 +156,7 @@ struct RegExNodeChar : public RegExNode {
|
||||
return next ? next->test(s, pos + 1) : pos + 1;
|
||||
}
|
||||
|
||||
static CharType parse_escape(const CharType*& c) {
|
||||
static CharType parse_escape(const CharType *&c) {
|
||||
|
||||
int point = 0;
|
||||
switch (c[1]) {
|
||||
@ -209,7 +206,7 @@ struct RegExNodeRange : public RegExNode {
|
||||
end = p_end;
|
||||
}
|
||||
|
||||
virtual int test(RegExSearch& s, int pos) const {
|
||||
virtual int test(RegExSearch &s, int pos) const {
|
||||
|
||||
if (s.end <= pos || 0 > pos)
|
||||
return -1;
|
||||
@ -233,7 +230,7 @@ struct RegExNodeShorthand : public RegExNode {
|
||||
repr = p_repr;
|
||||
}
|
||||
|
||||
virtual int test(RegExSearch& s, int pos) const {
|
||||
virtual int test(RegExSearch &s, int pos) const {
|
||||
|
||||
if (s.end <= pos || 0 > pos)
|
||||
return -1;
|
||||
@ -351,7 +348,7 @@ struct RegExNodeClass : public RegExNode {
|
||||
type = p_type;
|
||||
}
|
||||
|
||||
virtual int test(RegExSearch& s, int pos) const {
|
||||
virtual int test(RegExSearch &s, int pos) const {
|
||||
|
||||
if (s.end <= pos || 0 > pos)
|
||||
return -1;
|
||||
@ -362,9 +359,10 @@ struct RegExNodeClass : public RegExNode {
|
||||
return next ? next->test(s, pos + 1) : pos + 1;
|
||||
}
|
||||
|
||||
#define REGEX_CMP_CLASS(POS, NAME) if (cmp_class(POS, #NAME)) return Type_ ## NAME
|
||||
#define REGEX_CMP_CLASS(POS, NAME) \
|
||||
if (cmp_class(POS, #NAME)) return Type_##NAME
|
||||
|
||||
static Type parse_type(const CharType*& p_pos) {
|
||||
static Type parse_type(const CharType *&p_pos) {
|
||||
|
||||
REGEX_CMP_CLASS(p_pos, alnum);
|
||||
REGEX_CMP_CLASS(p_pos, alpha);
|
||||
@ -383,7 +381,7 @@ struct RegExNodeClass : public RegExNode {
|
||||
return Type_none;
|
||||
}
|
||||
|
||||
static bool cmp_class(const CharType*& p_pos, const char* p_text) {
|
||||
static bool cmp_class(const CharType *&p_pos, const char *p_text) {
|
||||
|
||||
unsigned int i = 0;
|
||||
for (i = 0; p_text[i] != '\0'; ++i)
|
||||
@ -405,7 +403,7 @@ struct RegExNodeAnchorStart : public RegExNode {
|
||||
length = 0;
|
||||
}
|
||||
|
||||
virtual int test(RegExSearch& s, int pos) const {
|
||||
virtual int test(RegExSearch &s, int pos) const {
|
||||
|
||||
if (pos != 0)
|
||||
return -1;
|
||||
@ -421,7 +419,7 @@ struct RegExNodeAnchorEnd : public RegExNode {
|
||||
length = 0;
|
||||
}
|
||||
|
||||
virtual int test(RegExSearch& s, int pos) const {
|
||||
virtual int test(RegExSearch &s, int pos) const {
|
||||
|
||||
if (pos != s.eof)
|
||||
return -1;
|
||||
@ -440,7 +438,7 @@ struct RegExNodeWordBoundary : public RegExNode {
|
||||
inverse = p_inverse;
|
||||
}
|
||||
|
||||
virtual int test(RegExSearch& s, int pos) const {
|
||||
virtual int test(RegExSearch &s, int pos) const {
|
||||
|
||||
bool left = false;
|
||||
bool right = false;
|
||||
@ -469,7 +467,7 @@ struct RegExNodeQuantifier : public RegExNode {
|
||||
int min;
|
||||
int max;
|
||||
bool greedy;
|
||||
RegExNode* child;
|
||||
RegExNode *child;
|
||||
|
||||
RegExNodeQuantifier(int p_min, int p_max) {
|
||||
|
||||
@ -485,18 +483,18 @@ struct RegExNodeQuantifier : public RegExNode {
|
||||
memdelete(child);
|
||||
}
|
||||
|
||||
virtual int test(RegExSearch& s, int pos) const {
|
||||
virtual int test(RegExSearch &s, int pos) const {
|
||||
|
||||
return test_step(s, pos, 0, pos);
|
||||
}
|
||||
|
||||
virtual int test_parent(RegExSearch& s, int pos) const {
|
||||
virtual int test_parent(RegExSearch &s, int pos) const {
|
||||
|
||||
s.complete = false;
|
||||
return pos;
|
||||
}
|
||||
|
||||
int test_step(RegExSearch& s, int pos, int level, int start) const {
|
||||
int test_step(RegExSearch &s, int pos, int level, int start) const {
|
||||
|
||||
if (pos > s.end)
|
||||
return -1;
|
||||
@ -554,9 +552,9 @@ struct RegExNodeBackReference : public RegExNode {
|
||||
id = p_id;
|
||||
}
|
||||
|
||||
virtual int test(RegExSearch& s, int pos) const {
|
||||
virtual int test(RegExSearch &s, int pos) const {
|
||||
|
||||
RegExMatch::Group& ref = s.match->captures[id];
|
||||
RegExMatch::Group &ref = s.match->captures[id];
|
||||
for (int i = 0; i < ref.length; ++i) {
|
||||
|
||||
if (pos + i >= s.end)
|
||||
@ -569,13 +567,12 @@ struct RegExNodeBackReference : public RegExNode {
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct RegExNodeGroup : public RegExNode {
|
||||
|
||||
bool inverse;
|
||||
bool reset_pos;
|
||||
Vector<RegExNode*> childset;
|
||||
RegExNode* back;
|
||||
Vector<RegExNode *> childset;
|
||||
RegExNode *back;
|
||||
|
||||
RegExNodeGroup() {
|
||||
|
||||
@ -592,7 +589,7 @@ struct RegExNodeGroup : public RegExNode {
|
||||
memdelete(childset[i]);
|
||||
}
|
||||
|
||||
virtual int test(RegExSearch& s, int pos) const {
|
||||
virtual int test(RegExSearch &s, int pos) const {
|
||||
|
||||
for (int i = 0; i < childset.size(); ++i) {
|
||||
|
||||
@ -622,7 +619,7 @@ struct RegExNodeGroup : public RegExNode {
|
||||
return -1;
|
||||
}
|
||||
|
||||
void add_child(RegExNode* node) {
|
||||
void add_child(RegExNode *node) {
|
||||
|
||||
node->parent = this;
|
||||
node->previous = back;
|
||||
@ -644,9 +641,9 @@ struct RegExNodeGroup : public RegExNode {
|
||||
back = NULL;
|
||||
}
|
||||
|
||||
RegExNode* swap_back(RegExNode* node) {
|
||||
RegExNode *swap_back(RegExNode *node) {
|
||||
|
||||
RegExNode* old = back;
|
||||
RegExNode *old = back;
|
||||
|
||||
if (old) {
|
||||
if (!old->previous)
|
||||
@ -670,9 +667,9 @@ struct RegExNodeCapturing : public RegExNodeGroup {
|
||||
id = p_id;
|
||||
}
|
||||
|
||||
virtual int test(RegExSearch& s, int pos) const {
|
||||
virtual int test(RegExSearch &s, int pos) const {
|
||||
|
||||
RegExMatch::Group& ref = s.match->captures[id];
|
||||
RegExMatch::Group &ref = s.match->captures[id];
|
||||
int old_start = ref.start;
|
||||
ref.start = pos;
|
||||
|
||||
@ -688,14 +685,14 @@ struct RegExNodeCapturing : public RegExNodeGroup {
|
||||
return res;
|
||||
}
|
||||
|
||||
virtual int test_parent(RegExSearch& s, int pos) const {
|
||||
virtual int test_parent(RegExSearch &s, int pos) const {
|
||||
|
||||
RegExMatch::Group& ref = s.match->captures[id];
|
||||
RegExMatch::Group &ref = s.match->captures[id];
|
||||
ref.length = pos - ref.start;
|
||||
return RegExNode::test_parent(s, pos);
|
||||
}
|
||||
|
||||
static Variant parse_name(const CharType*& c, bool p_allow_numeric) {
|
||||
static Variant parse_name(const CharType *&c, bool p_allow_numeric) {
|
||||
|
||||
if (c[1] == '0') {
|
||||
return -1;
|
||||
@ -732,13 +729,13 @@ struct RegExNodeLookAhead : public RegExNodeGroup {
|
||||
id = p_id;
|
||||
}
|
||||
|
||||
virtual int test(RegExSearch& s, int pos) const {
|
||||
virtual int test(RegExSearch &s, int pos) const {
|
||||
|
||||
s.lookahead_pos[id] = pos;
|
||||
return RegExNodeGroup::test(s, pos);
|
||||
}
|
||||
|
||||
virtual int test_parent(RegExSearch& s, int pos) const {
|
||||
virtual int test_parent(RegExSearch &s, int pos) const {
|
||||
|
||||
return RegExNode::test_parent(s, s.lookahead_pos[id]);
|
||||
}
|
||||
@ -755,7 +752,7 @@ struct RegExNodeLookBehind : public RegExNodeGroup {
|
||||
|
||||
virtual bool is_look_behind() { return true; }
|
||||
|
||||
virtual int test(RegExSearch& s, int pos) const {
|
||||
virtual int test(RegExSearch &s, int pos) const {
|
||||
|
||||
if (pos < length)
|
||||
return -1;
|
||||
@ -766,7 +763,7 @@ struct RegExNodeLookBehind : public RegExNodeGroup {
|
||||
struct RegExNodeBracket : public RegExNode {
|
||||
|
||||
bool inverse;
|
||||
Vector<RegExNode*> children;
|
||||
Vector<RegExNode *> children;
|
||||
|
||||
RegExNodeBracket() {
|
||||
|
||||
@ -781,7 +778,7 @@ struct RegExNodeBracket : public RegExNode {
|
||||
memdelete(children[i]);
|
||||
}
|
||||
|
||||
virtual int test(RegExSearch& s, int pos) const {
|
||||
virtual int test(RegExSearch &s, int pos) const {
|
||||
|
||||
for (int i = 0; i < children.size(); ++i) {
|
||||
|
||||
@ -803,7 +800,7 @@ struct RegExNodeBracket : public RegExNode {
|
||||
return -1;
|
||||
}
|
||||
|
||||
void add_child(RegExNode* node) {
|
||||
void add_child(RegExNode *node) {
|
||||
|
||||
node->parent = this;
|
||||
children.push_back(node);
|
||||
@ -816,16 +813,16 @@ struct RegExNodeBracket : public RegExNode {
|
||||
}
|
||||
};
|
||||
|
||||
#define REGEX_EXPAND_FAIL(MSG)\
|
||||
{\
|
||||
ERR_PRINT(MSG);\
|
||||
return String();\
|
||||
}
|
||||
#define REGEX_EXPAND_FAIL(MSG) \
|
||||
{ \
|
||||
ERR_PRINT(MSG); \
|
||||
return String(); \
|
||||
}
|
||||
|
||||
String RegExMatch::expand(const String& p_template) const {
|
||||
String RegExMatch::expand(const String &p_template) const {
|
||||
|
||||
String res;
|
||||
for (const CharType* c = p_template.c_str(); *c != '\0'; ++c) {
|
||||
for (const CharType *c = p_template.c_str(); *c != '\0'; ++c) {
|
||||
if (c[0] == '\\') {
|
||||
if (('1' <= c[1] && c[1] <= '9') || (c[1] == 'g' && c[2] == '{')) {
|
||||
|
||||
@ -850,9 +847,9 @@ String RegExMatch::expand(const String& p_template) const {
|
||||
|
||||
res += get_string(ref);
|
||||
|
||||
} else if (c[1] =='g' && c[2] == '<') {
|
||||
} else if (c[1] == 'g' && c[2] == '<') {
|
||||
|
||||
const CharType* d = &c[2];
|
||||
const CharType *d = &c[2];
|
||||
|
||||
Variant name = RegExNodeCapturing::parse_name(d, true);
|
||||
if (name == Variant(-1))
|
||||
@ -864,7 +861,7 @@ String RegExMatch::expand(const String& p_template) const {
|
||||
|
||||
} else {
|
||||
|
||||
const CharType* d = c;
|
||||
const CharType *d = c;
|
||||
CharType ch = RegExNodeChar::parse_escape(d);
|
||||
if (c == d)
|
||||
REGEX_EXPAND_FAIL("invalid escape token");
|
||||
@ -891,7 +888,7 @@ Array RegExMatch::get_group_array() const {
|
||||
|
||||
Array res;
|
||||
for (int i = 1; i < captures.size(); ++i) {
|
||||
const RegExMatch::Group& capture = captures[i];
|
||||
const RegExMatch::Group &capture = captures[i];
|
||||
if (capture.name.get_type() != Variant::INT)
|
||||
continue;
|
||||
|
||||
@ -916,7 +913,7 @@ Dictionary RegExMatch::get_name_dict() const {
|
||||
|
||||
Dictionary res;
|
||||
for (int i = 1; i < captures.size(); ++i) {
|
||||
const RegExMatch::Group& capture = captures[i];
|
||||
const RegExMatch::Group &capture = captures[i];
|
||||
if (capture.name.get_type() != Variant::STRING)
|
||||
continue;
|
||||
|
||||
@ -928,11 +925,11 @@ Dictionary RegExMatch::get_name_dict() const {
|
||||
return res;
|
||||
}
|
||||
|
||||
String RegExMatch::get_string(const Variant& p_name) const {
|
||||
String RegExMatch::get_string(const Variant &p_name) const {
|
||||
|
||||
for (int i = 0; i < captures.size(); ++i) {
|
||||
|
||||
const RegExMatch::Group& capture = captures[i];
|
||||
const RegExMatch::Group &capture = captures[i];
|
||||
|
||||
if (capture.name != p_name)
|
||||
continue;
|
||||
@ -945,7 +942,7 @@ String RegExMatch::get_string(const Variant& p_name) const {
|
||||
return String();
|
||||
}
|
||||
|
||||
int RegExMatch::get_start(const Variant& p_name) const {
|
||||
int RegExMatch::get_start(const Variant &p_name) const {
|
||||
|
||||
for (int i = 0; i < captures.size(); ++i)
|
||||
if (captures[i].name == p_name)
|
||||
@ -953,7 +950,7 @@ int RegExMatch::get_start(const Variant& p_name) const {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int RegExMatch::get_end(const Variant& p_name) const {
|
||||
int RegExMatch::get_end(const Variant &p_name) const {
|
||||
|
||||
for (int i = 0; i < captures.size(); ++i)
|
||||
if (captures[i].name == p_name)
|
||||
@ -962,7 +959,6 @@ int RegExMatch::get_end(const Variant& p_name) const {
|
||||
}
|
||||
|
||||
RegExMatch::RegExMatch() {
|
||||
|
||||
}
|
||||
|
||||
static bool RegEx_is_shorthand(CharType ch) {
|
||||
@ -981,14 +977,14 @@ static bool RegEx_is_shorthand(CharType ch) {
|
||||
return false;
|
||||
}
|
||||
|
||||
#define REGEX_COMPILE_FAIL(MSG)\
|
||||
{\
|
||||
ERR_PRINT(MSG);\
|
||||
clear();\
|
||||
return FAILED;\
|
||||
}
|
||||
#define REGEX_COMPILE_FAIL(MSG) \
|
||||
{ \
|
||||
ERR_PRINT(MSG); \
|
||||
clear(); \
|
||||
return FAILED; \
|
||||
}
|
||||
|
||||
Error RegEx::compile(const String& p_pattern) {
|
||||
Error RegEx::compile(const String &p_pattern) {
|
||||
|
||||
ERR_FAIL_COND_V(p_pattern.length() == 0, FAILED);
|
||||
|
||||
@ -998,21 +994,21 @@ Error RegEx::compile(const String& p_pattern) {
|
||||
clear();
|
||||
pattern = p_pattern;
|
||||
group_names.push_back(0);
|
||||
RegExNodeGroup* root_group = memnew(RegExNodeCapturing(0));
|
||||
RegExNodeGroup *root_group = memnew(RegExNodeCapturing(0));
|
||||
root = root_group;
|
||||
Vector<RegExNodeGroup*> stack;
|
||||
Vector<RegExNodeGroup *> stack;
|
||||
stack.push_back(root_group);
|
||||
int lookahead_level = 0;
|
||||
int numeric_groups = 0;
|
||||
const int numeric_max = 9;
|
||||
|
||||
for (const CharType* c = p_pattern.c_str(); *c != '\0'; ++c) {
|
||||
for (const CharType *c = p_pattern.c_str(); *c != '\0'; ++c) {
|
||||
|
||||
switch (c[0]) {
|
||||
case '(':
|
||||
if (c[1] == '?') {
|
||||
|
||||
RegExNodeGroup* group = NULL;
|
||||
RegExNodeGroup *group = NULL;
|
||||
switch (c[2]) {
|
||||
case ':':
|
||||
c = &c[2];
|
||||
@ -1033,7 +1029,7 @@ Error RegEx::compile(const String& p_pattern) {
|
||||
break;
|
||||
case 'P':
|
||||
if (c[3] == '<') {
|
||||
const CharType* d = &c[3];
|
||||
const CharType *d = &c[3];
|
||||
Variant name = RegExNodeCapturing::parse_name(d, false);
|
||||
if (name == Variant(-1))
|
||||
REGEX_COMPILE_FAIL("unrecognised character for group name");
|
||||
@ -1051,14 +1047,14 @@ Error RegEx::compile(const String& p_pattern) {
|
||||
|
||||
} else if (numeric_groups < numeric_max) {
|
||||
|
||||
RegExNodeCapturing* group = memnew(RegExNodeCapturing(group_names.size()));
|
||||
RegExNodeCapturing *group = memnew(RegExNodeCapturing(group_names.size()));
|
||||
group_names.push_back(++numeric_groups);
|
||||
stack[0]->add_child(group);
|
||||
stack.insert(0, group);
|
||||
|
||||
} else {
|
||||
|
||||
RegExNodeGroup* group = memnew(RegExNodeGroup());
|
||||
RegExNodeGroup *group = memnew(RegExNodeGroup());
|
||||
stack[0]->add_child(group);
|
||||
stack.insert(0, group);
|
||||
}
|
||||
@ -1105,10 +1101,10 @@ Error RegEx::compile(const String& p_pattern) {
|
||||
}
|
||||
|
||||
stack[0]->add_child(memnew(RegExNodeBackReference(ref)));
|
||||
}
|
||||
if (c[1] == 'g' && c[2] == '<') {
|
||||
|
||||
} if (c[1] =='g' && c[2] == '<') {
|
||||
|
||||
const CharType* d = &c[2];
|
||||
const CharType *d = &c[2];
|
||||
|
||||
Variant name = RegExNodeCapturing::parse_name(d, true);
|
||||
if (name == Variant(-1))
|
||||
@ -1144,103 +1140,100 @@ Error RegEx::compile(const String& p_pattern) {
|
||||
|
||||
} else {
|
||||
|
||||
const CharType* d = c;
|
||||
const CharType *d = c;
|
||||
CharType ch = RegExNodeChar::parse_escape(d);
|
||||
if (c == d)
|
||||
REGEX_COMPILE_FAIL("invalid escape token");
|
||||
stack[0]->add_child(memnew(RegExNodeChar(ch)));
|
||||
c = d;
|
||||
|
||||
}
|
||||
break;
|
||||
case '[':
|
||||
{
|
||||
RegExNodeBracket* bracket = memnew(RegExNodeBracket());
|
||||
stack[0]->add_child(bracket);
|
||||
if (c[1] == '^') {
|
||||
bracket->inverse = true;
|
||||
++c;
|
||||
}
|
||||
bool first_child = true;
|
||||
CharType previous_child;
|
||||
bool previous_child_single = false;
|
||||
while (true) {
|
||||
++c;
|
||||
if (!first_child && c[0] == ']') {
|
||||
case '[': {
|
||||
RegExNodeBracket *bracket = memnew(RegExNodeBracket());
|
||||
stack[0]->add_child(bracket);
|
||||
if (c[1] == '^') {
|
||||
bracket->inverse = true;
|
||||
++c;
|
||||
}
|
||||
bool first_child = true;
|
||||
CharType previous_child;
|
||||
bool previous_child_single = false;
|
||||
while (true) {
|
||||
++c;
|
||||
if (!first_child && c[0] == ']') {
|
||||
|
||||
break;
|
||||
break;
|
||||
|
||||
} else if (c[0] == '\0') {
|
||||
} else if (c[0] == '\0') {
|
||||
|
||||
REGEX_COMPILE_FAIL("unclosed bracket expression '['");
|
||||
REGEX_COMPILE_FAIL("unclosed bracket expression '['");
|
||||
|
||||
} else if (c[0] == '\\') {
|
||||
} else if (c[0] == '\\') {
|
||||
|
||||
if (RegEx_is_shorthand(c[1])) {
|
||||
bracket->add_child(memnew(RegExNodeShorthand(*(++c))));
|
||||
} else {
|
||||
const CharType* d = c;
|
||||
CharType ch = RegExNodeChar::parse_escape(d);
|
||||
if (c == d)
|
||||
REGEX_COMPILE_FAIL("invalid escape token");
|
||||
bracket->add_child(memnew(RegExNodeChar(ch)));
|
||||
c = d;
|
||||
previous_child = ch;
|
||||
previous_child_single = true;
|
||||
}
|
||||
|
||||
} else if (c[0] == ']' && c[1] == ':') {
|
||||
|
||||
const CharType* d = &c[2];
|
||||
RegExNodeClass::Type type = RegExNodeClass::parse_type(d);
|
||||
if (type != RegExNodeClass::Type_none) {
|
||||
|
||||
c = d;
|
||||
previous_child_single = false;
|
||||
|
||||
} else {
|
||||
|
||||
bracket->add_child(memnew(RegExNodeChar('[')));
|
||||
previous_child = '[';
|
||||
previous_child_single = true;
|
||||
}
|
||||
} else if (previous_child_single && c[0] == '-') {
|
||||
|
||||
if (c[1] != '\0' && c[1] != ']') {
|
||||
|
||||
CharType next;
|
||||
|
||||
if (c[1] == '\\') {
|
||||
const CharType* d = ++c;
|
||||
next = RegExNodeChar::parse_escape(d);
|
||||
if (c == d)
|
||||
REGEX_COMPILE_FAIL("invalid escape token");
|
||||
} else {
|
||||
next = *(++c);
|
||||
}
|
||||
|
||||
if (next < previous_child)
|
||||
REGEX_COMPILE_FAIL("text range out of order");
|
||||
|
||||
bracket->pop_back();
|
||||
bracket->add_child(memnew(RegExNodeRange(previous_child, next)));
|
||||
previous_child_single = false;
|
||||
} else {
|
||||
|
||||
bracket->add_child(memnew(RegExNodeChar('-')));
|
||||
previous_child = '-';
|
||||
previous_child_single = true;
|
||||
}
|
||||
if (RegEx_is_shorthand(c[1])) {
|
||||
bracket->add_child(memnew(RegExNodeShorthand(*(++c))));
|
||||
} else {
|
||||
|
||||
bracket->add_child(memnew(RegExNodeChar(c[0])));
|
||||
previous_child = c[0];
|
||||
const CharType *d = c;
|
||||
CharType ch = RegExNodeChar::parse_escape(d);
|
||||
if (c == d)
|
||||
REGEX_COMPILE_FAIL("invalid escape token");
|
||||
bracket->add_child(memnew(RegExNodeChar(ch)));
|
||||
c = d;
|
||||
previous_child = ch;
|
||||
previous_child_single = true;
|
||||
}
|
||||
first_child = false;
|
||||
|
||||
} else if (c[0] == ']' && c[1] == ':') {
|
||||
|
||||
const CharType *d = &c[2];
|
||||
RegExNodeClass::Type type = RegExNodeClass::parse_type(d);
|
||||
if (type != RegExNodeClass::Type_none) {
|
||||
|
||||
c = d;
|
||||
previous_child_single = false;
|
||||
|
||||
} else {
|
||||
|
||||
bracket->add_child(memnew(RegExNodeChar('[')));
|
||||
previous_child = '[';
|
||||
previous_child_single = true;
|
||||
}
|
||||
} else if (previous_child_single && c[0] == '-') {
|
||||
|
||||
if (c[1] != '\0' && c[1] != ']') {
|
||||
|
||||
CharType next;
|
||||
|
||||
if (c[1] == '\\') {
|
||||
const CharType *d = ++c;
|
||||
next = RegExNodeChar::parse_escape(d);
|
||||
if (c == d)
|
||||
REGEX_COMPILE_FAIL("invalid escape token");
|
||||
} else {
|
||||
next = *(++c);
|
||||
}
|
||||
|
||||
if (next < previous_child)
|
||||
REGEX_COMPILE_FAIL("text range out of order");
|
||||
|
||||
bracket->pop_back();
|
||||
bracket->add_child(memnew(RegExNodeRange(previous_child, next)));
|
||||
previous_child_single = false;
|
||||
} else {
|
||||
|
||||
bracket->add_child(memnew(RegExNodeChar('-')));
|
||||
previous_child = '-';
|
||||
previous_child_single = true;
|
||||
}
|
||||
} else {
|
||||
|
||||
bracket->add_child(memnew(RegExNodeChar(c[0])));
|
||||
previous_child = c[0];
|
||||
previous_child_single = true;
|
||||
}
|
||||
first_child = false;
|
||||
}
|
||||
break;
|
||||
} break;
|
||||
case '|':
|
||||
for (int i = 0; i < stack.size(); ++i)
|
||||
if (stack[i]->is_look_behind())
|
||||
@ -1259,82 +1252,81 @@ Error RegEx::compile(const String& p_pattern) {
|
||||
case '?':
|
||||
case '*':
|
||||
case '+':
|
||||
case '{':
|
||||
{
|
||||
int min_val = 0;
|
||||
int max_val = -1;
|
||||
bool valid = true;
|
||||
const CharType* d = c;
|
||||
bool max_set = true;
|
||||
switch (c[0]) {
|
||||
case '?':
|
||||
min_val = 0;
|
||||
max_val = 1;
|
||||
break;
|
||||
case '*':
|
||||
min_val = 0;
|
||||
max_val = -1;
|
||||
break;
|
||||
case '+':
|
||||
min_val = 1;
|
||||
max_val = -1;
|
||||
break;
|
||||
case '{':
|
||||
max_set = false;
|
||||
while (valid) {
|
||||
++d;
|
||||
if (d[0] == '}') {
|
||||
break;
|
||||
} else if (d[0] == ',') {
|
||||
max_set = true;
|
||||
} else if ('0' <= d[0] && d[0] <= '9') {
|
||||
if (max_set) {
|
||||
if (max_val < 0)
|
||||
max_val = int(d[0] - '0');
|
||||
else
|
||||
max_val = max_val * 10 + int(d[0] - '0');
|
||||
} else {
|
||||
min_val = min_val * 10 + int(d[0] - '0');
|
||||
}
|
||||
case '{': {
|
||||
int min_val = 0;
|
||||
int max_val = -1;
|
||||
bool valid = true;
|
||||
const CharType *d = c;
|
||||
bool max_set = true;
|
||||
switch (c[0]) {
|
||||
case '?':
|
||||
min_val = 0;
|
||||
max_val = 1;
|
||||
break;
|
||||
case '*':
|
||||
min_val = 0;
|
||||
max_val = -1;
|
||||
break;
|
||||
case '+':
|
||||
min_val = 1;
|
||||
max_val = -1;
|
||||
break;
|
||||
case '{':
|
||||
max_set = false;
|
||||
while (valid) {
|
||||
++d;
|
||||
if (d[0] == '}') {
|
||||
break;
|
||||
} else if (d[0] == ',') {
|
||||
max_set = true;
|
||||
} else if ('0' <= d[0] && d[0] <= '9') {
|
||||
if (max_set) {
|
||||
if (max_val < 0)
|
||||
max_val = int(d[0] - '0');
|
||||
else
|
||||
max_val = max_val * 10 + int(d[0] - '0');
|
||||
} else {
|
||||
valid = false;
|
||||
min_val = min_val * 10 + int(d[0] - '0');
|
||||
}
|
||||
} else {
|
||||
valid = false;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (!max_set)
|
||||
max_val = min_val;
|
||||
|
||||
if (valid) {
|
||||
|
||||
c = d;
|
||||
|
||||
if (stack[0]->back == NULL || !stack[0]->back->quantifiable)
|
||||
REGEX_COMPILE_FAIL("element not quantifiable");
|
||||
|
||||
if (min_val != max_val)
|
||||
for (int i = 0; i < stack.size(); ++i)
|
||||
if (stack[i]->is_look_behind())
|
||||
REGEX_COMPILE_FAIL("variable length quantifiers inside lookbehind not supported");
|
||||
|
||||
RegExNodeQuantifier* quant = memnew(RegExNodeQuantifier(min_val, max_val));
|
||||
quant->child = stack[0]->swap_back(quant);
|
||||
quant->child->previous = NULL;
|
||||
quant->child->parent = quant;
|
||||
|
||||
if (min_val == max_val && quant->child->length >= 0)
|
||||
quant->length = max_val * quant->child->length;
|
||||
|
||||
if (c[1] == '?') {
|
||||
quant->greedy = false;
|
||||
++c;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (!max_set)
|
||||
max_val = min_val;
|
||||
|
||||
if (valid) {
|
||||
|
||||
c = d;
|
||||
|
||||
if (stack[0]->back == NULL || !stack[0]->back->quantifiable)
|
||||
REGEX_COMPILE_FAIL("element not quantifiable");
|
||||
|
||||
if (min_val != max_val)
|
||||
for (int i = 0; i < stack.size(); ++i)
|
||||
if (stack[i]->is_look_behind())
|
||||
REGEX_COMPILE_FAIL("variable length quantifiers inside lookbehind not supported");
|
||||
|
||||
RegExNodeQuantifier *quant = memnew(RegExNodeQuantifier(min_val, max_val));
|
||||
quant->child = stack[0]->swap_back(quant);
|
||||
quant->child->previous = NULL;
|
||||
quant->child->parent = quant;
|
||||
|
||||
if (min_val == max_val && quant->child->length >= 0)
|
||||
quant->length = max_val * quant->child->length;
|
||||
|
||||
if (c[1] == '?') {
|
||||
quant->greedy = false;
|
||||
++c;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
default:
|
||||
stack[0]->add_child(memnew(RegExNodeChar(c[0])));
|
||||
break;
|
||||
@ -1345,7 +1337,7 @@ Error RegEx::compile(const String& p_pattern) {
|
||||
return OK;
|
||||
}
|
||||
|
||||
Ref<RegExMatch> RegEx::search(const String& p_text, int p_start, int p_end) const {
|
||||
Ref<RegExMatch> RegEx::search(const String &p_text, int p_start, int p_end) const {
|
||||
|
||||
ERR_FAIL_COND_V(!is_valid(), NULL);
|
||||
ERR_FAIL_COND_V(p_start < 0, NULL);
|
||||
@ -1382,7 +1374,7 @@ Ref<RegExMatch> RegEx::search(const String& p_text, int p_start, int p_end) cons
|
||||
return NULL;
|
||||
}
|
||||
|
||||
String RegEx::sub(const String& p_text, const String& p_replacement, bool p_all, int p_start, int p_end) const {
|
||||
String RegEx::sub(const String &p_text, const String &p_replacement, bool p_all, int p_start, int p_end) const {
|
||||
|
||||
ERR_FAIL_COND_V(!is_valid(), p_text);
|
||||
ERR_FAIL_COND_V(p_start < 0, p_text);
|
||||
@ -1400,7 +1392,7 @@ String RegEx::sub(const String& p_text, const String& p_replacement, bool p_all,
|
||||
|
||||
Ref<RegExMatch> m = search(text, start, p_end);
|
||||
|
||||
RegExMatch::Group& s = m->captures[0];
|
||||
RegExMatch::Group &s = m->captures[0];
|
||||
|
||||
if (s.start < 0)
|
||||
break;
|
||||
@ -1467,7 +1459,7 @@ RegEx::RegEx() {
|
||||
lookahead_depth = 0;
|
||||
}
|
||||
|
||||
RegEx::RegEx(const String& p_pattern) {
|
||||
RegEx::RegEx(const String &p_pattern) {
|
||||
|
||||
root = NULL;
|
||||
compile(p_pattern);
|
||||
@ -1481,27 +1473,26 @@ RegEx::~RegEx() {
|
||||
|
||||
void RegExMatch::_bind_methods() {
|
||||
|
||||
ClassDB::bind_method(D_METHOD("expand","template"),&RegExMatch::expand);
|
||||
ClassDB::bind_method(D_METHOD("get_group_count"),&RegExMatch::get_group_count);
|
||||
ClassDB::bind_method(D_METHOD("get_group_array"),&RegExMatch::get_group_array);
|
||||
ClassDB::bind_method(D_METHOD("get_names"),&RegExMatch::get_names);
|
||||
ClassDB::bind_method(D_METHOD("get_name_dict"),&RegExMatch::get_name_dict);
|
||||
ClassDB::bind_method(D_METHOD("get_string","name"),&RegExMatch::get_string, DEFVAL(0));
|
||||
ClassDB::bind_method(D_METHOD("get_start","name"),&RegExMatch::get_start, DEFVAL(0));
|
||||
ClassDB::bind_method(D_METHOD("get_end","name"),&RegExMatch::get_end, DEFVAL(0));
|
||||
ClassDB::bind_method(D_METHOD("expand", "template"), &RegExMatch::expand);
|
||||
ClassDB::bind_method(D_METHOD("get_group_count"), &RegExMatch::get_group_count);
|
||||
ClassDB::bind_method(D_METHOD("get_group_array"), &RegExMatch::get_group_array);
|
||||
ClassDB::bind_method(D_METHOD("get_names"), &RegExMatch::get_names);
|
||||
ClassDB::bind_method(D_METHOD("get_name_dict"), &RegExMatch::get_name_dict);
|
||||
ClassDB::bind_method(D_METHOD("get_string", "name"), &RegExMatch::get_string, DEFVAL(0));
|
||||
ClassDB::bind_method(D_METHOD("get_start", "name"), &RegExMatch::get_start, DEFVAL(0));
|
||||
ClassDB::bind_method(D_METHOD("get_end", "name"), &RegExMatch::get_end, DEFVAL(0));
|
||||
}
|
||||
|
||||
void RegEx::_bind_methods() {
|
||||
|
||||
ClassDB::bind_method(D_METHOD("clear"),&RegEx::clear);
|
||||
ClassDB::bind_method(D_METHOD("compile","pattern"),&RegEx::compile);
|
||||
ClassDB::bind_method(D_METHOD("search","text","start","end"),&RegEx::search, DEFVAL(0), DEFVAL(-1));
|
||||
ClassDB::bind_method(D_METHOD("sub","text","replacement","all","start","end"),&RegEx::sub, DEFVAL(false), DEFVAL(0), DEFVAL(-1));
|
||||
ClassDB::bind_method(D_METHOD("is_valid"),&RegEx::is_valid);
|
||||
ClassDB::bind_method(D_METHOD("get_pattern"),&RegEx::get_pattern);
|
||||
ClassDB::bind_method(D_METHOD("get_group_count"),&RegEx::get_group_count);
|
||||
ClassDB::bind_method(D_METHOD("get_names"),&RegEx::get_names);
|
||||
ClassDB::bind_method(D_METHOD("clear"), &RegEx::clear);
|
||||
ClassDB::bind_method(D_METHOD("compile", "pattern"), &RegEx::compile);
|
||||
ClassDB::bind_method(D_METHOD("search", "text", "start", "end"), &RegEx::search, DEFVAL(0), DEFVAL(-1));
|
||||
ClassDB::bind_method(D_METHOD("sub", "text", "replacement", "all", "start", "end"), &RegEx::sub, DEFVAL(false), DEFVAL(0), DEFVAL(-1));
|
||||
ClassDB::bind_method(D_METHOD("is_valid"), &RegEx::is_valid);
|
||||
ClassDB::bind_method(D_METHOD("get_pattern"), &RegEx::get_pattern);
|
||||
ClassDB::bind_method(D_METHOD("get_group_count"), &RegEx::get_group_count);
|
||||
ClassDB::bind_method(D_METHOD("get_names"), &RegEx::get_names);
|
||||
|
||||
ADD_PROPERTY(PropertyInfo(Variant::STRING, "pattern"), "compile", "get_pattern");
|
||||
}
|
||||
|
||||
|
||||
@ -30,11 +30,11 @@
|
||||
#ifndef REGEX_H
|
||||
#define REGEX_H
|
||||
|
||||
#include "core/vector.h"
|
||||
#include "core/ustring.h"
|
||||
#include "core/dictionary.h"
|
||||
#include "core/reference.h"
|
||||
#include "core/resource.h"
|
||||
#include "core/ustring.h"
|
||||
#include "core/vector.h"
|
||||
|
||||
class RegExNode;
|
||||
|
||||
@ -57,12 +57,10 @@ class RegExMatch : public Reference {
|
||||
friend class RegExNodeBackReference;
|
||||
|
||||
protected:
|
||||
|
||||
static void _bind_methods();
|
||||
|
||||
public:
|
||||
|
||||
String expand(const String& p_template) const;
|
||||
String expand(const String &p_template) const;
|
||||
|
||||
int get_group_count() const;
|
||||
Array get_group_array() const;
|
||||
@ -70,34 +68,31 @@ public:
|
||||
Array get_names() const;
|
||||
Dictionary get_name_dict() const;
|
||||
|
||||
String get_string(const Variant& p_name) const;
|
||||
int get_start(const Variant& p_name) const;
|
||||
int get_end(const Variant& p_name) const;
|
||||
String get_string(const Variant &p_name) const;
|
||||
int get_start(const Variant &p_name) const;
|
||||
int get_end(const Variant &p_name) const;
|
||||
|
||||
RegExMatch();
|
||||
|
||||
};
|
||||
|
||||
class RegEx : public Resource {
|
||||
|
||||
GDCLASS(RegEx, Resource);
|
||||
|
||||
RegExNode* root;
|
||||
RegExNode *root;
|
||||
Vector<Variant> group_names;
|
||||
String pattern;
|
||||
int lookahead_depth;
|
||||
|
||||
protected:
|
||||
|
||||
static void _bind_methods();
|
||||
|
||||
public:
|
||||
|
||||
void clear();
|
||||
Error compile(const String& p_pattern);
|
||||
Error compile(const String &p_pattern);
|
||||
|
||||
Ref<RegExMatch> search(const String& p_text, int p_start = 0, int p_end = -1) const;
|
||||
String sub(const String& p_text, const String& p_replacement, bool p_all = false, int p_start = 0, int p_end = -1) const;
|
||||
Ref<RegExMatch> search(const String &p_text, int p_start = 0, int p_end = -1) const;
|
||||
String sub(const String &p_text, const String &p_replacement, bool p_all = false, int p_start = 0, int p_end = -1) const;
|
||||
|
||||
bool is_valid() const;
|
||||
String get_pattern() const;
|
||||
@ -105,10 +100,8 @@ public:
|
||||
Array get_names() const;
|
||||
|
||||
RegEx();
|
||||
RegEx(const String& p_pattern);
|
||||
RegEx(const String &p_pattern);
|
||||
~RegEx();
|
||||
|
||||
};
|
||||
|
||||
#endif // REGEX_H
|
||||
|
||||
|
||||
@ -38,6 +38,4 @@ void register_regex_types() {
|
||||
}
|
||||
|
||||
void unregister_regex_types() {
|
||||
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user