RegExpFlags.h (5857B)
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/. */ 6 7 /* Regular expression flags. */ 8 9 #ifndef js_RegExpFlags_h 10 #define js_RegExpFlags_h 11 12 #include "mozilla/Assertions.h" // MOZ_ASSERT 13 #include "mozilla/Attributes.h" // MOZ_IMPLICIT 14 15 #include <ostream> // ostream 16 #include <stdint.h> // uint8_t 17 18 namespace JS { 19 20 /** 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. 24 */ 25 class RegExpFlag { 26 // WARNING TO SPIDERMONKEY HACKERS (embedders must assume these values can 27 // change): 28 // 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. 32 33 public: 34 /** 35 * Add .indices property to the match result, i.e. /d 36 */ 37 static constexpr uint8_t HasIndices = 0b0100'0000; 38 39 /** 40 * Act globally and find *all* matches (rather than stopping after just the 41 * first one), i.e. /g. 42 */ 43 static constexpr uint8_t Global = 0b0000'0010; 44 45 /** 46 * Interpret regular expression source text case-insensitively by folding 47 * uppercase letters to lowercase, i.e. /i. 48 */ 49 static constexpr uint8_t IgnoreCase = 0b0000'0001; 50 51 /** Treat ^ and $ as begin and end of line, i.e. /m. */ 52 static constexpr uint8_t Multiline = 0b0000'0100; 53 54 /* Allow . to match newline characters, i.e. /s. */ 55 static constexpr uint8_t DotAll = 0b0010'0000; 56 57 /** Use Unicode semantics, i.e. /u. */ 58 static constexpr uint8_t Unicode = 0b0001'0000; 59 60 /** Use Unicode Sets semantics, i.e. /v. */ 61 static constexpr uint8_t UnicodeSets = 0b1000'0000; 62 63 /** Only match starting from <regular expression>.lastIndex, i.e. /y. */ 64 static constexpr uint8_t Sticky = 0b0000'1000; 65 66 /** No regular expression flags. */ 67 static constexpr uint8_t NoFlags = 0b0000'0000; 68 69 /** All regular expression flags. */ 70 static constexpr uint8_t AllFlags = 0b1111'1111; 71 }; 72 73 /** 74 * A collection of regular expression flags. Individual flag values may be 75 * combined into a collection using bitwise operators. 76 */ 77 class RegExpFlags { 78 public: 79 using Flag = uint8_t; 80 81 private: 82 Flag flags_ = 0; 83 84 public: 85 RegExpFlags() = default; 86 87 MOZ_IMPLICIT RegExpFlags(Flag flags) : flags_(flags) { 88 MOZ_ASSERT((flags & RegExpFlag::AllFlags) == flags, 89 "flags must not contain unrecognized flags"); 90 } 91 92 RegExpFlags(const RegExpFlags&) = default; 93 RegExpFlags& operator=(const RegExpFlags&) = default; 94 95 bool operator==(const RegExpFlags& other) const { 96 return flags_ == other.flags_; 97 } 98 99 bool operator!=(const RegExpFlags& other) const { return !(*this == other); } 100 101 RegExpFlags& operator&=(const RegExpFlags& rhs) { 102 flags_ &= rhs.flags_; 103 return *this; 104 } 105 106 RegExpFlags& operator|=(const RegExpFlags& rhs) { 107 flags_ |= rhs.flags_; 108 return *this; 109 } 110 111 RegExpFlags operator&(Flag flag) const { return RegExpFlags(flags_ & flag); } 112 113 RegExpFlags operator|(Flag flag) const { return RegExpFlags(flags_ | flag); } 114 115 RegExpFlags operator^(Flag flag) const { return RegExpFlags(flags_ ^ flag); } 116 117 RegExpFlags operator~() const { 118 return RegExpFlags(~flags_ & RegExpFlag::AllFlags); 119 } 120 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; } 129 130 explicit operator bool() const { return flags_ != 0; } 131 132 Flag value() const { return flags_; } 133 constexpr operator Flag() const { return flags_; } 134 135 void set(Flag flags, bool value) { 136 if (value) { 137 flags_ |= flags; 138 } else { 139 flags_ &= ~flags; 140 } 141 } 142 }; 143 144 inline RegExpFlags& operator&=(RegExpFlags& flags, RegExpFlags::Flag flag) { 145 flags = flags & flag; 146 return flags; 147 } 148 149 inline RegExpFlags& operator|=(RegExpFlags& flags, RegExpFlags::Flag flag) { 150 flags = flags | flag; 151 return flags; 152 } 153 154 inline RegExpFlags& operator^=(RegExpFlags& flags, RegExpFlags::Flag flag) { 155 flags = flags ^ flag; 156 return flags; 157 } 158 159 inline RegExpFlags operator&(const RegExpFlags& lhs, const RegExpFlags& rhs) { 160 RegExpFlags result = lhs; 161 result &= rhs; 162 return result; 163 } 164 165 inline RegExpFlags operator|(const RegExpFlags& lhs, const RegExpFlags& rhs) { 166 RegExpFlags result = lhs; 167 result |= rhs; 168 return result; 169 } 170 171 inline bool MaybeParseRegExpFlag(char c, RegExpFlags::Flag* flag) { 172 switch (c) { 173 case 'd': 174 *flag = RegExpFlag::HasIndices; 175 return true; 176 case 'g': 177 *flag = RegExpFlag::Global; 178 return true; 179 case 'i': 180 *flag = RegExpFlag::IgnoreCase; 181 return true; 182 case 'm': 183 *flag = RegExpFlag::Multiline; 184 return true; 185 case 's': 186 *flag = RegExpFlag::DotAll; 187 return true; 188 case 'u': 189 *flag = RegExpFlag::Unicode; 190 return true; 191 case 'v': 192 *flag = RegExpFlag::UnicodeSets; 193 return true; 194 case 'y': 195 *flag = RegExpFlag::Sticky; 196 return true; 197 default: 198 return false; 199 } 200 } 201 202 std::ostream& operator<<(std::ostream& os, RegExpFlags flags); 203 204 } // namespace JS 205 206 #endif // js_RegExpFlags_h