6#include <private/qv4mm_p.h>
11#include "private/qlocale_tools_p.h"
13#include <QtCore/QDebug>
14#if QT_CONFIG(regularexpression)
15#include <QtCore/qregularexpression.h>
20#include <private/qv4alloca_p.h>
28void Heap::RegExpObject::init()
31 Scope scope(internalClass->engine);
40 Scope scope(internalClass->engine);
41 this->value.set(scope.engine,
value->d());
53 bool inBracket =
false;
57 switch (
c.unicode()) {
67 ecmaPattern += wc[
i++];
82#if QT_CONFIG(regularexpression)
90 Scope scope(internalClass->engine);
96 : CompiledData::
RegExp::RegExp_NoFlags;
114#if QT_CONFIG(regularexpression)
147 if (offset < 0 || offset >
s.size()) {
156 regExpCtor->d()->clearLastMatch();
158 if (
result == JSC::Yarr::offsetNoMatch) {
171 int strlen =
s.size();
172 for (
int i = 0;
i <
len; ++
i) {
173 int start = matchOffsets[
i * 2];
174 int end = matchOffsets[
i * 2 + 1];
180 array->setArrayLengthUnchecked(
len);
184 RegExpCtor::Data *dd = regExpCtor->d();
186 dd->lastInput.set(scope.
engine,
str->d());
187 dd->lastMatchStart = matchOffsets[0];
188 dd->lastMatchEnd = matchOffsets[1];
193 return array.asReturnedValue();
204void Heap::RegExpCtor::clearLastMatch()
207 lastInput.set(internalClass->engine, internalClass->engine->id_empty()->d());
222 return re ? true :
false;
228 if (!
f->isUndefined()) {
259 if (newTarget == fo) {
260 if (patternIsRegExp && (argc < 2 || argv[1].
isUndefined())) {
263 if (patternConstructor->
sameValue(*newTarget))
264 return pattern->asReturnedValue();
275 if (
f->isUndefined()) {
277 return Encode(
scope.engine->newRegExpObject(regexp));
279 pattern = *re->value()->pattern;
281 }
else if (patternIsRegExp) {
284 if (!
p->isUndefined())
286 if (
scope.hasException())
288 if (
f->isUndefined())
292 if (!
p->isUndefined())
294 if (
scope.hasException())
298 if (
scope.hasException())
302 if (!regexp->isValid()) {
311 obj->setProtoFromNewTarget(newTarget);
312 return obj->asReturnedValue();
328 ctor->addSymbolSpecies();
331 ctor->defineAccessorProperty(
QStringLiteral(
"lastMatch"), method_get_lastMatch_n<0>,
nullptr);
332 ctor->defineAccessorProperty(
QStringLiteral(
"$&"), method_get_lastMatch_n<0>,
nullptr);
333 ctor->defineAccessorProperty(
QStringLiteral(
"$1"), method_get_lastMatch_n<1>,
nullptr);
334 ctor->defineAccessorProperty(
QStringLiteral(
"$2"), method_get_lastMatch_n<2>,
nullptr);
335 ctor->defineAccessorProperty(
QStringLiteral(
"$3"), method_get_lastMatch_n<3>,
nullptr);
336 ctor->defineAccessorProperty(
QStringLiteral(
"$4"), method_get_lastMatch_n<4>,
nullptr);
337 ctor->defineAccessorProperty(
QStringLiteral(
"$5"), method_get_lastMatch_n<5>,
nullptr);
338 ctor->defineAccessorProperty(
QStringLiteral(
"$6"), method_get_lastMatch_n<6>,
nullptr);
339 ctor->defineAccessorProperty(
QStringLiteral(
"$7"), method_get_lastMatch_n<7>,
nullptr);
340 ctor->defineAccessorProperty(
QStringLiteral(
"$8"), method_get_lastMatch_n<8>,
nullptr);
341 ctor->defineAccessorProperty(
QStringLiteral(
"$9"), method_get_lastMatch_n<9>,
nullptr);
383 if (offset < 0 || offset >
s.size()) {
392 regExpCtor->d()->clearLastMatch();
401 if (
r->value()->captureCount()) {
402 int start = matchOffsets[0];
403 int end = matchOffsets[1];
407 RegExpCtor::Data *dd = regExpCtor->d();
409 dd->lastMatchStart = matchOffsets[0];
410 dd->lastMatchEnd = matchOffsets[1];
412 r->setLastIndex(matchOffsets[1]);
428 return result->asReturnedValue();
433 return re->builtinExec(
engine,
s);
531 if (matchString->d()->length() == 0) {
570 return a->asReturnedValue();
577 a->push_back(matchString);
608 int lengthS =
s->toQString().size();
612 bool functionalReplace = !!replaceFunction;
613 if (!functionalReplace)
618 bool unicode =
false;
645 int nextSourcePosition = 0;
646 int resultsLength =
results->getLength();
648 for (
int i = 0;
i < resultsLength; ++
i) {
653 int nCaptures = resultObject->getLength();
654 nCaptures =
qMax(nCaptures - 1, 0);
659 QString m = matchString->toQString();
660 int matchLength =
m.size();
670 while (
n <= nCaptures) {
672 if (!
v->isUndefined())
677 if (functionalReplace) {
678 cData.
args[0] = matchString;
680 cData.
args[nCaptures + 2] =
s;
681 ScopedValue replValue(scope, replaceFunction->call(cData));
690 if (
position >= nextSourcePosition) {
691 accumulatedResult +=
QStringView{
s->toQString()}.
mid(nextSourcePosition,
position - nextSourcePosition) + replacement;
692 nextSourcePosition =
position + matchLength;
695 if (nextSourcePosition < lengthS) {
696 accumulatedResult +=
QStringView{
s->toQString()}.
mid(nextSourcePosition);
713 if (previousLastIndex->
toNumber() != 0) {
723 if (!currentLastIndex->
sameValue(previousLastIndex)) {
784 return A->asReturnedValue();
792 return A->asReturnedValue();
824 if (lengthA ==
limit)
825 return A->asReturnedValue();
828 uint numberOfCaptures =
qMax(zz->getLength() - 1, 0ll);
829 for (
uint i = 1;
i <= numberOfCaptures; ++
i) {
833 if (lengthA ==
limit)
834 return A->asReturnedValue();
842 return A->asReturnedValue();
909 r->d()->value.set(scope.
engine, re->value());
919 if (
res->isUndefined())
929 if (
res->isUndefined())
943 QString lastInput = regExpCtor->lastInput()->toQString();
951 QString lastInput = regExpCtor->lastInput()->toQString();
constexpr bool isLowSurrogate() const noexcept
Returns true if the QChar is the low part of a UTF16 surrogate (for example if its code point is in r...
constexpr char16_t unicode() const noexcept
Returns the numeric Unicode value of the QChar.
constexpr bool isHighSurrogate() const noexcept
Returns true if the QChar is the high part of a UTF16 surrogate (for example if its code point is in ...
void push_back(parameter_type t)
\inmodule QtCore \reentrant
PatternOptions patternOptions() const
Returns the pattern options for the regular expression.
@ InvertedGreedinessOption
QString pattern() const
Returns the pattern string of the regular expression.
constexpr QStringView mid(qsizetype pos, qsizetype n=-1) const noexcept
Returns the substring of length length starting at position start in this object.
\macro QT_RESTRICTED_CAST_FROM_ASCII
void reserve(qsizetype size)
Ensures the string has space for at least size characters.
qsizetype size() const
Returns the number of characters in this string.
QString mid(qsizetype position, qsizetype n=-1) const
Returns a string that contains n characters of this string, starting at the specified position index.
const QChar at(qsizetype i) const
Returns the character at the given index position in the string.
bool contains(QChar c, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
QString left(qsizetype n) const
Returns a substring that contains the n leftmost characters of the string.
ManagedType::Data * alloc(Args &&... args)
Combined button and popup list for selecting options.
\qmltype Particle \inqmlmodule QtQuick.Particles
static QString toString(QV4::ReturnedValue v)
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
constexpr const T & qMin(const T &a, const T &b)
constexpr const T & qMax(const T &a, const T &b)
GLboolean GLboolean GLboolean b
GLsizei const GLfloat * v
[13]
GLuint GLfloat GLfloat GLfloat GLfloat GLfloat z
GLboolean GLboolean GLboolean GLboolean a
[7]
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLenum GLuint GLintptr offset
GLsizei GLsizei GLchar * source
GLdouble GLdouble GLdouble GLdouble q
static qreal position(const QQuickItem *item, QQuickAnchors::Anchor anchorLine)
QLatin1StringView QLatin1String
#define QStringLiteral(str)
static bool match(const uchar *found, uint foundLen, const char *target, uint targetLen)
#define Q_ALLOCA_VAR(type, name, size)
static int advanceStringIndex(int index, const QString &str, bool unicode)
static bool isRegExp(ExecutionEngine *e, const QV4::Value *arg)
static QString minimalPattern(const QString &pattern)
uint parseFlags(Scope &scope, const QV4::Value *f)
static void advanceLastIndexOnEmptyMatch(ExecutionEngine *e, bool unicode, QV4::Object *rx, const String *matchString, const QString &str)
#define RETURN_UNDEFINED()
#define DEFINE_OBJECT_VTABLE(classname)
\inmodule QtCore \reentrant
static constexpr ReturnedValue undefined()
static constexpr ReturnedValue null()
Heap::InternalClass * internalClasses(InternalClassType icType)
MemoryManager * memoryManager
String * id_sticky() const
Symbol * symbol_split() const
String * id_unicode() const
String * id_flags() const
Heap::String * newString(const QString &s=QString())
FunctionObject * regExpCtor() const
String * id_length() const
String * id_global() const
String * id_multiline() const
String * id_ignoreCase() const
Symbol * symbol_replace() const
String * id_toString() const
String * id_prototype() const
String * id_lastIndex() const
String * id_index() const
Symbol * symbol_match() const
Heap::ArrayObject * newArrayObject(int count=0)
ReturnedValue throwSyntaxError(const QString &message)
String * id_source() const
Object * regExpPrototype() const
ReturnedValue throwTypeError()
Symbol * symbol_search() const
ReturnedValue callAsConstructor(const JSCallData &data) const
Heap::ExecutionContext * scope() const
ReturnedValue asReturnedValue() const
ExecutionEngine * engine() const
void defineDefaultProperty(StringOrSymbol *name, const Value &value, PropertyAttributes attributes=Attr_Data|Attr_NotEnumerable)
void defineAccessorProperty(const QString &name, VTable::Call getter, VTable::Call setter)
void setProperty(const InternalClassEntry &entry, const Property *p)
ReturnedValue get(StringOrSymbol *name, bool *hasProperty=nullptr, const Value *receiver=nullptr) const
static PropertyKey fromArrayIndex(uint idx)
Heap::String * lastInput()
ReturnedValue builtinExec(ExecutionEngine *engine, const String *s)
void setLastIndex(int index)
static ReturnedValue method_get_leftContext(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_compile(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue execFirstMatch(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_get_sticky(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_get_unicode(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_get_flags(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_get_source(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_get_lastMatch_n(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_split(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_match(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_toString(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_get_multiline(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
void init(ExecutionEngine *engine, Object *ctor)
static ReturnedValue method_exec(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_search(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_get_input(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_get_rightContext(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_get_lastParen(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_replace(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_test(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue exec(ExecutionEngine *engine, const Object *o, const String *s)
static ReturnedValue method_get_ignoreCase(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_get_global(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static QString getSubstitution(const QString &matched, const QString &str, int position, const Value *captures, int nCaptures, const QString &replacement)
static Heap::RegExp * create(ExecutionEngine *engine, const QString &pattern, uint flags=CompiledData::RegExp::RegExp_NoFlags)
V4_NEEDS_DESTROY QString pattern() const
Value * alloc(qint64 nValues) const =delete
bool hasException() const
constexpr ReturnedValue asReturnedValue() const
static constexpr VTable::CallAsConstructor virtualCallAsConstructor
static constexpr VTable::Call virtualCall
static constexpr Value fromInt32(int i)
Heap::String * toString(ExecutionEngine *e) const
unsigned int toUInt32() const
static constexpr Value undefinedValue()
static constexpr Value fromReturnedValue(ReturnedValue val)
QString toQString() const
bool sameValue(Value other) const
static constexpr Value nullValue()