1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 * vim: set ts=8 sts=2 et sw=2 tw=80:
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 /* Regular expression flags. */
9 #ifndef js_RegExpFlags_h
10 #define js_RegExpFlags_h
12 #include "mozilla/Assertions.h" // MOZ_ASSERT
13 #include "mozilla/Attributes.h" // MOZ_IMPLICIT
15 #include <ostream> // ostream
16 #include <stdint.h> // uint8_t
21 * Regular expression flag values, suitable for initializing a collection of
22 * regular expression flags as defined below in |RegExpFlags|. Flags are listed
23 * in alphabetical order by syntax -- /d, /g, /i, /m, /s, /u, /v, /y.
26 // WARNING TO SPIDERMONKEY HACKERS (embedders must assume these values can
29 // Flag-bit values appear in XDR and structured clone data formats, so none of
30 // these values can be changed (including to assign values in numerically
31 // ascending order) unless you also add a translation layer.
35 * Add .indices property to the match result, i.e. /d
37 static constexpr uint8_t HasIndices
= 0b0100'0000;
40 * Act globally and find *all* matches (rather than stopping after just the
41 * first one), i.e. /g.
43 static constexpr uint8_t Global
= 0b0000'0010;
46 * Interpret regular expression source text case-insensitively by folding
47 * uppercase letters to lowercase, i.e. /i.
49 static constexpr uint8_t IgnoreCase
= 0b0000'0001;
51 /** Treat ^ and $ as begin and end of line, i.e. /m. */
52 static constexpr uint8_t Multiline
= 0b0000'0100;
54 /* Allow . to match newline characters, i.e. /s. */
55 static constexpr uint8_t DotAll
= 0b0010'0000;
57 /** Use Unicode semantics, i.e. /u. */
58 static constexpr uint8_t Unicode
= 0b0001'0000;
60 /** Use Unicode Sets semantics, i.e. /v. */
61 static constexpr uint8_t UnicodeSets
= 0b1000'0000;
63 /** Only match starting from <regular expression>.lastIndex, i.e. /y. */
64 static constexpr uint8_t Sticky
= 0b0000'1000;
66 /** No regular expression flags. */
67 static constexpr uint8_t NoFlags
= 0b0000'0000;
69 /** All regular expression flags. */
70 static constexpr uint8_t AllFlags
= 0b1111'1111;
74 * A collection of regular expression flags. Individual flag values may be
75 * combined into a collection using bitwise operators.
85 RegExpFlags() = default;
87 MOZ_IMPLICIT
RegExpFlags(Flag flags
) : flags_(flags
) {
88 MOZ_ASSERT((flags
& RegExpFlag::AllFlags
) == flags
,
89 "flags must not contain unrecognized flags");
92 RegExpFlags(const RegExpFlags
&) = default;
93 RegExpFlags
& operator=(const RegExpFlags
&) = default;
95 bool operator==(const RegExpFlags
& other
) const {
96 return flags_
== other
.flags_
;
99 bool operator!=(const RegExpFlags
& other
) const { return !(*this == other
); }
101 RegExpFlags
& operator&=(const RegExpFlags
& rhs
) {
102 flags_
&= rhs
.flags_
;
106 RegExpFlags
& operator|=(const RegExpFlags
& rhs
) {
107 flags_
|= rhs
.flags_
;
111 RegExpFlags
operator&(Flag flag
) const { return RegExpFlags(flags_
& flag
); }
113 RegExpFlags
operator|(Flag flag
) const { return RegExpFlags(flags_
| flag
); }
115 RegExpFlags
operator^(Flag flag
) const { return RegExpFlags(flags_
^ flag
); }
117 RegExpFlags
operator~() const {
118 return RegExpFlags(~flags_
& RegExpFlag::AllFlags
);
121 bool hasIndices() const { return flags_
& RegExpFlag::HasIndices
; }
122 bool global() const { return flags_
& RegExpFlag::Global
; }
123 bool ignoreCase() const { return flags_
& RegExpFlag::IgnoreCase
; }
124 bool multiline() const { return flags_
& RegExpFlag::Multiline
; }
125 bool dotAll() const { return flags_
& RegExpFlag::DotAll
; }
126 bool unicode() const { return flags_
& RegExpFlag::Unicode
; }
127 bool unicodeSets() const { return flags_
& RegExpFlag::UnicodeSets
; }
128 bool sticky() const { return flags_
& RegExpFlag::Sticky
; }
130 explicit operator bool() const { return flags_
!= 0; }
132 Flag
value() const { return flags_
; }
133 constexpr operator Flag() const { return flags_
; }
135 void set(Flag flags
, bool value
) {
144 inline RegExpFlags
& operator&=(RegExpFlags
& flags
, RegExpFlags::Flag flag
) {
145 flags
= flags
& flag
;
149 inline RegExpFlags
& operator|=(RegExpFlags
& flags
, RegExpFlags::Flag flag
) {
150 flags
= flags
| flag
;
154 inline RegExpFlags
& operator^=(RegExpFlags
& flags
, RegExpFlags::Flag flag
) {
155 flags
= flags
^ flag
;
159 inline RegExpFlags
operator&(const RegExpFlags
& lhs
, const RegExpFlags
& rhs
) {
160 RegExpFlags result
= lhs
;
165 inline RegExpFlags
operator|(const RegExpFlags
& lhs
, const RegExpFlags
& rhs
) {
166 RegExpFlags result
= lhs
;
171 inline bool MaybeParseRegExpFlag(char c
, RegExpFlags::Flag
* flag
) {
174 *flag
= RegExpFlag::HasIndices
;
177 *flag
= RegExpFlag::Global
;
180 *flag
= RegExpFlag::IgnoreCase
;
183 *flag
= RegExpFlag::Multiline
;
186 *flag
= RegExpFlag::DotAll
;
189 *flag
= RegExpFlag::Unicode
;
192 *flag
= RegExpFlag::UnicodeSets
;
195 *flag
= RegExpFlag::Sticky
;
202 std::ostream
& operator<<(std::ostream
& os
, RegExpFlags flags
);
206 #endif // js_RegExpFlags_h