Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings
This repository was archived by the owner on Aug 31, 2021. It is now read-only.

Commit b29140d

Browse filesBrowse files
committed
[[ Bug 21505 ]] Implement matches operator
This patch implements a new operator `matches` to match a string to a regex or wildcard pattern.
1 parent 4f7c373 commit b29140d
Copy full SHA for b29140d

File tree

8 files changed

+102
-2
lines changed
Filter options

8 files changed

+102
-2
lines changed

‎engine/src/executionerrors.h

Copy file name to clipboardExpand all lines: engine/src/executionerrors.h
+7Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2774,6 +2774,13 @@ enum Exec_errors
27742774
// {EE-0908} fontLanguage: bad font name
27752775
EE_FONTLANGUAGE_BADFONTNAME,
27762776

2777+
// {EE-0909} matches: illegal type for right operand
2778+
EE_MATCHES_BADRIGHT,
2779+
2780+
// {EE-0910} matches: illegal type for left operand
2781+
EE_MATCHES_BADLEFT,
2782+
2783+
27772784
};
27782785

27792786
extern const char *MCexecutionerrors;

‎engine/src/lextable.cpp

Copy file name to clipboardExpand all lines: engine/src/lextable.cpp
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1201,6 +1201,7 @@ const LT factor_table[] =
12011201
{"maskdata", TT_PROPERTY, P_MASK_DATA},
12021202
{"maskpixmapid", TT_PROPERTY, P_MASK_PIXMAP_ID},
12031203
{"matchchunk", TT_FUNCTION, F_MATCH_CHUNK},
1204+
{"matches", TT_BINOP, O_MATCHES},
12041205
{"matchtext", TT_FUNCTION, F_MATCH_TEXT},
12051206
{"matrixmultiply", TT_FUNCTION, F_MATRIX_MULTIPLY},
12061207
{"max", TT_FUNCTION, F_MAX},

‎engine/src/newobj.cpp

Copy file name to clipboardExpand all lines: engine/src/newobj.cpp
+3-1Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -939,7 +939,9 @@ MCExpression *MCN_new_operator(int2 which)
939939
return new MCBeginsWith;
940940
case O_ENDS_WITH:
941941
return new MCEndsWith;
942-
default:
942+
case O_MATCHES:
943+
return new MCMatches;
944+
default:
943945
return new MCExpression;
944946
}
945947
}

‎engine/src/operator.cpp

Copy file name to clipboardExpand all lines: engine/src/operator.cpp
+48Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,54 @@ void MCEndsWith::eval_ctxt(MCExecContext &ctxt, MCExecValue &r_value)
185185
MCExecValueTraits<bool>::set(r_value, t_result);
186186
}
187187

188+
Parse_stat MCMatches::parse(MCScriptPoint& sp, Boolean the)
189+
{
190+
initpoint(sp);
191+
192+
if (sp . skip_token(SP_SUGAR, TT_UNDEFINED, SG_WILDCARD) == PS_NORMAL)
193+
{
194+
m_matchmode = MA_WILDCARD;
195+
}
196+
else if (sp . skip_token(SP_SUGAR, TT_UNDEFINED, SG_REGEX) == PS_NORMAL)
197+
{
198+
m_matchmode = MA_REGEX;
199+
}
200+
else
201+
{
202+
MCperror -> add(PE_MATCHES_NOMODE, sp);
203+
return PS_ERROR;
204+
}
205+
206+
// Skip the optional pattern keyword
207+
sp.skip_token(SP_SUGAR, TT_UNDEFINED, SG_PATTERN);
208+
209+
return PS_NORMAL;
210+
}
211+
212+
void MCMatches::eval_ctxt(MCExecContext &ctxt, MCExecValue &r_value)
213+
{
214+
MCAutoStringRef t_left, t_right;
215+
bool t_result;
216+
217+
if (!ctxt . EvalExprAsStringRef(left, EE_MATCHES_BADLEFT, &t_left)
218+
|| !ctxt . EvalExprAsStringRef(right, EE_MATCHES_BADRIGHT, &t_right))
219+
return;
220+
221+
if (m_matchmode == MA_REGEX)
222+
{
223+
MCStringsEvalMatchText(ctxt, *t_left, *t_right, nullptr, 0, t_result);
224+
}
225+
else
226+
{
227+
t_result = MCStringWildcardMatch(*t_left,
228+
MCRangeMake(0, MCStringGetLength(*t_left)),
229+
*t_right,
230+
ctxt.GetStringComparisonType());
231+
}
232+
233+
MCExecValueTraits<bool>::set(r_value, t_result);
234+
}
235+
188236
///////////////////////////////////////////////////////////////////////////////
189237
//
190238
// Numeric operators

‎engine/src/operator.h

Copy file name to clipboardExpand all lines: engine/src/operator.h
+9Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -491,4 +491,13 @@ class MCEndsWith : public MCBeginsEndsWith
491491
virtual void eval_ctxt(MCExecContext &ctxt, MCExecValue &r_value);
492492
};
493493

494+
class MCMatches : public MCBinaryOperator
495+
{
496+
public:
497+
virtual Parse_stat parse(MCScriptPoint&, Boolean the);
498+
virtual void eval_ctxt(MCExecContext &ctxt, MCExecValue &r_value);
499+
private:
500+
Match_mode m_matchmode;
501+
};
502+
494503
#endif

‎engine/src/parsedef.h

Copy file name to clipboardExpand all lines: engine/src/parsedef.h
+2-1Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -783,7 +783,8 @@ enum Operators {
783783
O_OR,
784784
O_WRAP,
785785
O_BEGINS_WITH,
786-
O_ENDS_WITH
786+
O_ENDS_WITH,
787+
O_MATCHES
787788
};
788789

789790
// return codes from parsers

‎engine/src/parseerrors.h

Copy file name to clipboardExpand all lines: engine/src/parseerrors.h
+3Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1796,6 +1796,9 @@ enum Parse_errors
17961796
// {PE-0583} fontLanguage: bad type expression
17971797
PE_FONTLANGUAGE_BADPARAM,
17981798

1799+
// {PE-0584} matches: missing match mode 'regex' or 'wildcard'
1800+
PE_MATCHES_NOMODE,
1801+
17991802
};
18001803

18011804
extern const char *MCparsingerrors;
+29Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
script "CoreLogicMatches"
2+
/*
3+
Copyright (C) 2018 LiveCode Ltd.
4+
5+
This file is part of LiveCode.
6+
7+
LiveCode is free software; you can redistribute it and/or modify it under
8+
the terms of the GNU General Public License v3 as published by the Free
9+
Software Foundation.
10+
11+
LiveCode is distributed in the hope that it will be useful, but WITHOUT ANY
12+
WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+
for more details.
15+
16+
You should have received a copy of the GNU General Public License
17+
along with LiveCode. If not see <http://www.gnu.org/licenses/>. */
18+
19+
on TestMatchesWildcard
20+
TestAssert "wildcard pattern matches", "foobar" matches wildcard pattern "*b*"
21+
TestAssert "wildcard pattern does not match", not ("foobar" matches wildcard pattern "*z*")
22+
end TestMatchesWildcard
23+
24+
constant kEmailRegex = "^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$"
25+
26+
on TestMatchesRegex
27+
TestAssert "regex pattern matches", "support@livecode.com" matches regex pattern kEmailRegex
28+
TestAssert "regex pattern does not match", not ("support dot livecode dot com" matches regex pattern kEmailRegex)
29+
end TestMatchesRegex

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.