2019-04-02 06:16:43 +03:00
|
|
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
|
|
|
* vim: set ts=8 sts=2 et sw=2 tw=80:
|
|
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
|
|
|
|
/* Regular expression flags. */
|
|
|
|
|
|
|
|
#ifndef js_RegExpFlags_h
|
|
|
|
#define js_RegExpFlags_h
|
|
|
|
|
|
|
|
#include "mozilla/Assertions.h" // MOZ_ASSERT
|
|
|
|
#include "mozilla/Attributes.h" // MOZ_IMPLICIT
|
|
|
|
|
|
|
|
#include <stdint.h> // uint8_t
|
|
|
|
|
|
|
|
namespace JS {
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Regular expression flag values, suitable for initializing a collection of
|
|
|
|
* regular expression flags as defined below in |RegExpFlags|. Flags are listed
|
2021-03-11 01:10:14 +03:00
|
|
|
* in alphabetical order by syntax -- /d, /g, /i, /m, /s, /u, /y.
|
2019-04-02 06:16:43 +03:00
|
|
|
*/
|
|
|
|
class RegExpFlag {
|
|
|
|
// WARNING TO SPIDERMONKEY HACKERS (embedders must assume these values can
|
|
|
|
// change):
|
|
|
|
//
|
|
|
|
// Flag-bit values appear in XDR and structured clone data formats, so none of
|
|
|
|
// these values can be changed (including to assign values in numerically
|
|
|
|
// ascending order) unless you also add a translation layer.
|
|
|
|
|
|
|
|
public:
|
2021-03-11 01:10:14 +03:00
|
|
|
/**
|
|
|
|
* Add .indices property to the match result, i.e. /d
|
|
|
|
*/
|
|
|
|
static constexpr uint8_t HasIndices = 0b100'0000;
|
|
|
|
|
2019-04-02 06:16:43 +03:00
|
|
|
/**
|
|
|
|
* Act globally and find *all* matches (rather than stopping after just the
|
|
|
|
* first one), i.e. /g.
|
|
|
|
*/
|
2021-03-11 01:10:14 +03:00
|
|
|
static constexpr uint8_t Global = 0b000'0010;
|
2019-04-02 06:16:43 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Interpret regular expression source text case-insensitively by folding
|
|
|
|
* uppercase letters to lowercase, i.e. /i.
|
|
|
|
*/
|
2021-03-11 01:10:14 +03:00
|
|
|
static constexpr uint8_t IgnoreCase = 0b000'0001;
|
2019-04-02 06:16:43 +03:00
|
|
|
|
|
|
|
/** Treat ^ and $ as begin and end of line, i.e. /m. */
|
2021-03-11 01:10:14 +03:00
|
|
|
static constexpr uint8_t Multiline = 0b000'0100;
|
2020-03-21 17:21:04 +03:00
|
|
|
|
|
|
|
/* Allow . to match newline characters, i.e. /s. */
|
2021-03-11 01:10:14 +03:00
|
|
|
static constexpr uint8_t DotAll = 0b010'0000;
|
2019-04-02 06:16:43 +03:00
|
|
|
|
|
|
|
/** Use Unicode semantics, i.e. /u. */
|
2021-03-11 01:10:14 +03:00
|
|
|
static constexpr uint8_t Unicode = 0b001'0000;
|
2019-04-02 06:16:43 +03:00
|
|
|
|
|
|
|
/** Only match starting from <regular expression>.lastIndex, i.e. /y. */
|
2021-03-11 01:10:14 +03:00
|
|
|
static constexpr uint8_t Sticky = 0b000'1000;
|
2019-04-02 06:16:43 +03:00
|
|
|
|
|
|
|
/** No regular expression flags. */
|
2021-03-11 01:10:14 +03:00
|
|
|
static constexpr uint8_t NoFlags = 0b000'0000;
|
2019-04-02 06:16:43 +03:00
|
|
|
|
|
|
|
/** All regular expression flags. */
|
2021-03-11 01:10:14 +03:00
|
|
|
static constexpr uint8_t AllFlags = 0b111'1111;
|
2019-04-02 06:16:43 +03:00
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* A collection of regular expression flags. Individual flag values may be
|
|
|
|
* combined into a collection using bitwise operators.
|
|
|
|
*/
|
|
|
|
class RegExpFlags {
|
|
|
|
public:
|
|
|
|
using Flag = uint8_t;
|
|
|
|
|
|
|
|
private:
|
|
|
|
Flag flags_;
|
|
|
|
|
|
|
|
public:
|
|
|
|
RegExpFlags() = default;
|
|
|
|
|
|
|
|
MOZ_IMPLICIT RegExpFlags(Flag flags) : flags_(flags) {
|
|
|
|
MOZ_ASSERT((flags & RegExpFlag::AllFlags) == flags,
|
|
|
|
"flags must not contain unrecognized flags");
|
|
|
|
}
|
|
|
|
|
|
|
|
RegExpFlags(const RegExpFlags&) = default;
|
|
|
|
|
|
|
|
bool operator==(const RegExpFlags& other) const {
|
|
|
|
return flags_ == other.flags_;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool operator!=(const RegExpFlags& other) const { return !(*this == other); }
|
|
|
|
|
2020-03-21 17:21:04 +03:00
|
|
|
RegExpFlags& operator&=(const RegExpFlags& rhs) {
|
|
|
|
flags_ &= rhs.flags_;
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
RegExpFlags& operator|=(const RegExpFlags& rhs) {
|
|
|
|
flags_ |= rhs.flags_;
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
2019-04-02 06:16:43 +03:00
|
|
|
RegExpFlags operator&(Flag flag) const { return RegExpFlags(flags_ & flag); }
|
|
|
|
|
|
|
|
RegExpFlags operator|(Flag flag) const { return RegExpFlags(flags_ | flag); }
|
|
|
|
|
|
|
|
RegExpFlags operator^(Flag flag) const { return RegExpFlags(flags_ ^ flag); }
|
|
|
|
|
2020-03-21 17:21:04 +03:00
|
|
|
RegExpFlags operator~() const {
|
|
|
|
return RegExpFlags(~flags_ & RegExpFlag::AllFlags);
|
|
|
|
}
|
2019-04-02 06:16:43 +03:00
|
|
|
|
2021-03-11 01:10:14 +03:00
|
|
|
bool hasIndices() const { return flags_ & RegExpFlag::HasIndices; }
|
2019-04-02 06:16:43 +03:00
|
|
|
bool global() const { return flags_ & RegExpFlag::Global; }
|
|
|
|
bool ignoreCase() const { return flags_ & RegExpFlag::IgnoreCase; }
|
|
|
|
bool multiline() const { return flags_ & RegExpFlag::Multiline; }
|
2020-03-21 17:21:04 +03:00
|
|
|
bool dotAll() const { return flags_ & RegExpFlag::DotAll; }
|
2019-04-02 06:16:43 +03:00
|
|
|
bool unicode() const { return flags_ & RegExpFlag::Unicode; }
|
|
|
|
bool sticky() const { return flags_ & RegExpFlag::Sticky; }
|
|
|
|
|
|
|
|
explicit operator bool() const { return flags_ != 0; }
|
|
|
|
|
|
|
|
Flag value() const { return flags_; }
|
|
|
|
};
|
|
|
|
|
|
|
|
inline RegExpFlags& operator&=(RegExpFlags& flags, RegExpFlags::Flag flag) {
|
|
|
|
flags = flags & flag;
|
|
|
|
return flags;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline RegExpFlags& operator|=(RegExpFlags& flags, RegExpFlags::Flag flag) {
|
|
|
|
flags = flags | flag;
|
|
|
|
return flags;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline RegExpFlags& operator^=(RegExpFlags& flags, RegExpFlags::Flag flag) {
|
|
|
|
flags = flags ^ flag;
|
|
|
|
return flags;
|
|
|
|
}
|
|
|
|
|
2020-03-21 17:21:04 +03:00
|
|
|
inline RegExpFlags operator&(const RegExpFlags& lhs, const RegExpFlags& rhs) {
|
|
|
|
RegExpFlags result = lhs;
|
|
|
|
result &= rhs;
|
|
|
|
return lhs;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline RegExpFlags operator|(const RegExpFlags& lhs, const RegExpFlags& rhs) {
|
|
|
|
RegExpFlags result = lhs;
|
|
|
|
result |= rhs;
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2019-04-02 06:16:43 +03:00
|
|
|
} // namespace JS
|
|
|
|
|
|
|
|
#endif // js_RegExpFlags_h
|