tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

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