Full Code of google/re2 for AI

main 972a15cedd00 cached
134 files
1.3 MB
425.0k tokens
942 symbols
1 requests
Download .txt
Showing preview only (1,357K chars total). Download the full file or copy to clipboard to get everything.
Repository: google/re2
Branch: main
Commit: 972a15cedd00
Files: 134
Total size: 1.3 MB

Directory structure:
gitextract_qg203vwa/

├── .bazelrc
├── .bcr/
│   ├── metadata.template.json
│   ├── presubmit.yml
│   └── source.template.json
├── .github/
│   ├── bazel.sh
│   ├── cmake.sh
│   └── workflows/
│       ├── ci-bazel.yml
│       ├── ci-cmake.yml
│       ├── ci.yml
│       ├── pages.yml
│       ├── python.yml
│       ├── release-bazel.yml
│       └── release.yml
├── .gitignore
├── BUILD.bazel
├── CMakeLists.txt
├── CONTRIBUTING.md
├── LICENSE
├── MODULE.bazel
├── Makefile
├── README.md
├── SECURITY.md
├── WORKSPACE.bazel
├── WORKSPACE.bzlmod
├── app/
│   ├── BUILD.bazel
│   ├── _re2.cc
│   ├── _re2.d.ts
│   ├── app.ts
│   ├── build.sh
│   ├── index.html
│   ├── package.json
│   ├── rollup.config.js
│   └── tsconfig.json
├── benchlog/
│   ├── benchplot.py
│   └── mktable
├── doc/
│   ├── mksyntaxgo
│   ├── mksyntaxhtml
│   ├── mksyntaxwiki
│   ├── syntax.html
│   └── syntax.txt
├── lib/
│   └── git/
│       └── commit-msg.hook
├── libre2.symbols
├── libre2.symbols.darwin
├── python/
│   ├── BUILD.bazel
│   ├── README
│   ├── _re2.cc
│   ├── re2.py
│   ├── re2_test.py
│   ├── setup.py
│   └── toolchains/
│       └── generate.py
├── re2/
│   ├── bitmap256.cc
│   ├── bitmap256.h
│   ├── bitstate.cc
│   ├── compile.cc
│   ├── dfa.cc
│   ├── filtered_re2.cc
│   ├── filtered_re2.h
│   ├── fuzzing/
│   │   └── re2_fuzzer.cc
│   ├── make_perl_groups.pl
│   ├── make_unicode_casefold.py
│   ├── make_unicode_groups.py
│   ├── mimics_pcre.cc
│   ├── nfa.cc
│   ├── onepass.cc
│   ├── parse.cc
│   ├── perl_groups.cc
│   ├── pod_array.h
│   ├── prefilter.cc
│   ├── prefilter.h
│   ├── prefilter_tree.cc
│   ├── prefilter_tree.h
│   ├── prog.cc
│   ├── prog.h
│   ├── re2.cc
│   ├── re2.h
│   ├── regexp.cc
│   ├── regexp.h
│   ├── set.cc
│   ├── set.h
│   ├── simplify.cc
│   ├── sparse_array.h
│   ├── sparse_set.h
│   ├── stringpiece.h
│   ├── testing/
│   │   ├── backtrack.cc
│   │   ├── charclass_test.cc
│   │   ├── compile_test.cc
│   │   ├── dfa_test.cc
│   │   ├── dump.cc
│   │   ├── exhaustive1_test.cc
│   │   ├── exhaustive2_test.cc
│   │   ├── exhaustive3_test.cc
│   │   ├── exhaustive_test.cc
│   │   ├── exhaustive_tester.cc
│   │   ├── exhaustive_tester.h
│   │   ├── filtered_re2_test.cc
│   │   ├── mimics_pcre_test.cc
│   │   ├── null_walker.cc
│   │   ├── parse_test.cc
│   │   ├── possible_match_test.cc
│   │   ├── random_test.cc
│   │   ├── re2_arg_test.cc
│   │   ├── re2_test.cc
│   │   ├── regexp_benchmark.cc
│   │   ├── regexp_generator.cc
│   │   ├── regexp_generator.h
│   │   ├── regexp_test.cc
│   │   ├── required_prefix_test.cc
│   │   ├── search_test.cc
│   │   ├── set_test.cc
│   │   ├── simplify_test.cc
│   │   ├── string_generator.cc
│   │   ├── string_generator.h
│   │   ├── string_generator_test.cc
│   │   ├── tester.cc
│   │   └── tester.h
│   ├── tostring.cc
│   ├── unicode.py
│   ├── unicode_casefold.cc
│   ├── unicode_casefold.h
│   ├── unicode_groups.cc
│   ├── unicode_groups.h
│   └── walker-inl.h
├── re2.pc.in
├── re2Config.cmake.in
├── runtests
├── testinstall.cc
├── ucs2.diff
└── util/
    ├── malloc_counter.h
    ├── pcre.cc
    ├── pcre.h
    ├── rune.cc
    ├── strutil.cc
    ├── strutil.h
    └── utf.h

================================================
FILE CONTENTS
================================================

================================================
FILE: .bazelrc
================================================
# Copyright 2022 The RE2 Authors.  All Rights Reserved.
# Use of this source code is governed by a BSD-style
# license that can be found in the LICENSE file.

# Enable layering check features. Useful on Clang only.
build --features=layering_check
# Enable parse headers features. Enforcing that headers are self-contained.
build --features=parse_headers

# Abseil requires C++17 at minimum.
build --enable_platform_specific_config
build:linux --cxxopt=-std=c++17
build:macos --cxxopt=-std=c++17
build:windows --cxxopt=/std:c++17

# Print test logs for failed tests.
test --test_output=errors

# https://bazel.build/configure/best-practices#bazelrc-file
try-import %workspace%/user.bazelrc


================================================
FILE: .bcr/metadata.template.json
================================================
{
  "homepage": "https://github.com/google/re2",
  "maintainers": [
      {
          "email": "rsc@google.com",
          "github": "rsc",
          "github_user_id": 104030,
          "name": "Russ Cox"
      }
  ],
  "repository": [
      "github:google/re2"
  ],
  "versions": [],
  "yanked_versions": {}
}


================================================
FILE: .bcr/presubmit.yml
================================================
matrix:
  platform:
  - rockylinux8
  - debian10
  - ubuntu2004
  - macos
  bazel:
  - 7.x
  - 8.x

tasks:
  unix_build:
    platform: ${{ platform }}
    bazel: ${{ bazel }}
    build_flags:
    - '--cxxopt=-std=c++17'
    build_targets:
    - '@re2//:re2'
    - '@re2//python:re2'
  windows_build:
    platform: windows
    bazel: ${{ bazel }}
    build_flags:
    - '--cxxopt=/std:c++17'
    build_targets:
    - '@re2//:re2'
    - '@re2//python:re2'

bcr_test_module:
  module_path: '.'
  matrix:
    platform:
    - rockylinux8
    - debian10
    - ubuntu2004
    - macos
    - windows
    bazel:
    - 7.x
    - 8.x
  tasks:
    unix_test:
      platform: ${{ platform }}
      bazel: ${{ bazel }}
      test_flags:
      - '--cxxopt=-std=c++17'
      test_targets:
      - '//:small_tests'
      - '//python:all'
    windows_test:
      platform: windows
      bazel: ${{ bazel }}
      test_flags:
      - '--cxxopt=/std:c++17'
      test_targets:
      - '//:small_tests'
      - '//python:all'


================================================
FILE: .bcr/source.template.json
================================================
{
  "integrity": "",
  "strip_prefix": "{REPO}-{VERSION}",
  "url": "https://github.com/{OWNER}/{REPO}/releases/download/{TAG}/{REPO}-{TAG}.zip"
}


================================================
FILE: .github/bazel.sh
================================================
#!/bin/bash
set -eux

# Disable MSYS/MSYS2 path conversion, which interferes with Bazel.
export MSYS_NO_PATHCONV='1'
export MSYS2_ARG_CONV_EXCL='*'

for compilation_mode in dbg opt
do
  bazel clean
  bazel build \
    --extra_toolchains=//python/toolchains:all \
    --compilation_mode=${compilation_mode} -- \
    //:re2 \
    //python:re2
  bazel test \
    --extra_toolchains=//python/toolchains:all \
    --compilation_mode=${compilation_mode} -- \
    //:small_tests \
    //python:all
done

exit 0


================================================
FILE: .github/cmake.sh
================================================
#!/bin/bash
set -eux

for CMAKE_BUILD_TYPE in Debug Release
do
  cmake . -D CMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} -D RE2_BUILD_TESTING=ON "$@"
  cmake --build . --config ${CMAKE_BUILD_TYPE} --clean-first
  ctest -C ${CMAKE_BUILD_TYPE} --output-on-failure -E 'dfa|exhaustive|random'
done

exit 0


================================================
FILE: .github/workflows/ci-bazel.yml
================================================
name: CI (Bazel)
on:
  pull_request:
    branches: [main]
  push:
    branches: [main, rsc-testing]
permissions:
  contents: read
jobs:
  build:
    runs-on: ${{ matrix.os }}
    strategy:
      fail-fast: false
      matrix:
        os: [macos-latest, ubuntu-latest, windows-latest]
        # Keep in sync with python.yml.
        ver: ['3.10', '3.11', '3.12', '3.13', '3.14']
    steps:
      - uses: actions/checkout@v4.2.2
      - uses: bazel-contrib/setup-bazel@0.15.0
        with:
          bazelisk-version: '1.x'
      - uses: actions/setup-python@v5.6.0
        with:
          python-version: ${{ matrix.ver }}
      - name: Prepare Python ${{ matrix.ver }} environment
        run: |
          python -m pip install --upgrade pip
          python -m pip install --upgrade absl-py mypy
          python python/toolchains/generate.py
        shell: bash
      - run: .github/bazel.sh
        shell: bash
      # TODO(junyer): Run mypy as per https://github.com/google/re2/issues/496.


================================================
FILE: .github/workflows/ci-cmake.yml
================================================
name: CI (CMake)
on:
  pull_request:
    branches: [main]
  push:
    branches: [main, rsc-testing]
permissions:
  contents: read
jobs:
  build-linux:
    runs-on: ubuntu-latest
    strategy:
      fail-fast: false
      matrix:
        build_shared_libs: [OFF, ON]
    steps:
      - uses: actions/checkout@v4.2.2
      - name: Install Abseil, GoogleTest and Benchmark
        run: |
          vcpkg update
          vcpkg install abseil gtest benchmark
        shell: bash
      - run: |
          .github/cmake.sh -D BUILD_SHARED_LIBS=${{ matrix.build_shared_libs }} \
            -D CMAKE_TOOLCHAIN_FILE=/usr/local/share/vcpkg/scripts/buildsystems/vcpkg.cmake
        shell: bash
  build-macos:
    runs-on: macos-latest
    strategy:
      fail-fast: false
      matrix:
        build_shared_libs: [OFF, ON]
    steps:
      - uses: actions/checkout@v4.2.2
      - name: Install Abseil, GoogleTest and Benchmark
        run: |
          brew update
          brew install abseil googletest google-benchmark
        shell: bash
      - run: .github/cmake.sh -D BUILD_SHARED_LIBS=${{ matrix.build_shared_libs }}
        shell: bash
  build-windows:
    runs-on: windows-latest
    strategy:
      fail-fast: false
      matrix:
        build_shared_libs: [OFF, ON]
    steps:
      - uses: actions/checkout@v4.2.2
      - name: Install Abseil, GoogleTest and Benchmark
        run: |
          vcpkg update
          vcpkg install abseil gtest benchmark
        shell: bash
      - run: |
          .github/cmake.sh -D BUILD_SHARED_LIBS=${{ matrix.build_shared_libs }} \
            -D CMAKE_TOOLCHAIN_FILE=C:/vcpkg/scripts/buildsystems/vcpkg.cmake
        shell: bash


================================================
FILE: .github/workflows/ci.yml
================================================
name: CI
on:
  pull_request:
    branches: [main]
  push:
    branches: [main, rsc-testing]
permissions:
  contents: read
jobs:
  build-appleclang:
    runs-on: macos-latest
    strategy:
      fail-fast: false
      matrix:
        ver: [17, 20]
    env:
      CC: clang
      CXX: clang++
      # Unlike GCC and upstream Clang, AppleClang still defaults to `-std=c++98`
      # for some reason. Also, the macOS image on GitHub Actions provides wildly
      # numbered Xcode versions. Thus, rather than varying the compiler version,
      # we set the `-std` flag explicitly in order to vary the language version.
      # (The other two flags are the default provided for CXXFLAGS in Makefile.)
      CXXFLAGS: -O3 -g -std=c++${{ matrix.ver }}
    steps:
      - uses: actions/checkout@v4.2.2
      - name: Install Abseil, GoogleTest and Benchmark
        run: |
          brew update
          brew install abseil googletest google-benchmark
        shell: bash
      - run: make && make test
        shell: bash
  build-clang:
    runs-on: ubuntu-latest
    strategy:
      fail-fast: false
      matrix:
        ver: [18, 19, 20]
    env:
      CC: clang-${{ matrix.ver }}
      CXX: clang++-${{ matrix.ver }}
      PKG_CONFIG_PATH: /usr/local/share/vcpkg/installed/x64-linux/lib/pkgconfig
    steps:
      - uses: actions/checkout@v4.2.2
      - name: Install Clang ${{ matrix.ver }}
        run: |
          # Avoid `Conflicts: python3-lldb-x.y` between packages.
          sudo apt purge -y python3-lldb-14
          wget https://apt.llvm.org/llvm.sh
          chmod +x ./llvm.sh
          sudo ./llvm.sh ${{ matrix.ver }}
        shell: bash
      - name: Install Abseil, GoogleTest and Benchmark
        run: |
          vcpkg update
          vcpkg install abseil gtest benchmark
        shell: bash
      - run: make && make test
        shell: bash
  build-gcc:
    runs-on: ubuntu-latest
    strategy:
      fail-fast: false
      matrix:
        ver: [12, 13, 14]
    env:
      CC: gcc-${{ matrix.ver }}
      CXX: g++-${{ matrix.ver }}
      PKG_CONFIG_PATH: /usr/local/share/vcpkg/installed/x64-linux/lib/pkgconfig
    steps:
      - uses: actions/checkout@v4.1.7
      - name: Install Abseil, GoogleTest and Benchmark
        run: |
          vcpkg update
          vcpkg install abseil gtest benchmark
        shell: bash
      - run: make && make test
        shell: bash


================================================
FILE: .github/workflows/pages.yml
================================================
name: Pages
on:
  workflow_dispatch:
permissions:
  contents: read
jobs:
  build:
    runs-on: ubuntu-latest
    container:
      image: emscripten/emsdk
      # Don't run as root within the container.
      # Neither Git nor Bazel appreciates that.
      # 1001 is the GitHub Actions runner user.
      options: --init --user 1001
    env:
      BAZELISK_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      # Bazel fails if the username is unknown.
      USER: runner
    steps:
      - uses: actions/checkout@v4.2.2
      - uses: bazel-contrib/setup-bazel@0.15.0
        with:
          bazelisk-version: '1.x'
      - run: app/build.sh
        shell: bash
      - uses: actions/upload-pages-artifact@v3.0.1
        with:
          path: app/deploy
  deploy:
    needs:
      - build
    permissions:
      contents: read
      # Needed for Pages deployment.
      id-token: write
      pages: write
    environment: github-pages
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4.2.2
      - uses: actions/deploy-pages@v4.0.5


================================================
FILE: .github/workflows/python.yml
================================================
name: Python
on:
  workflow_dispatch:
    inputs:
      build:
        required: true
        type: number
      force-sdist:
        required: false
        type: boolean
        default: false
permissions:
  contents: read
jobs:
  wheel-linux:
    name: Linux ${{ matrix.os }}, ${{ matrix.arch.name }}, Python ${{ matrix.ver }}
    runs-on: ${{ matrix.arch.runs-on }}
    container:
      image: quay.io/pypa/${{ matrix.os }}_${{ matrix.arch.python-name }}
      # Don't run as root within the container.
      # Neither Git nor Bazel appreciates that.
      # 1001 is the GitHub Actions runner user.
      options: --init --user 1001
    strategy:
      fail-fast: false
      matrix:
        arch:
          - { name: X64,   python-name: x86_64,  runs-on: [ubuntu-latest]              }
          - { name: ARM64, python-name: aarch64, runs-on: [ubuntu-24.04-arm] }
        os: [manylinux_2_28]
        # Keep in sync with ci-bazel.yml and list below.
        # Also, when bumping the minimum version, update ../../python/setup.py.
        ver: ['3.10', '3.11', '3.12', '3.13', '3.14']
    env:
      BAZELISK_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      PYTHON: /usr/local/bin/python${{ matrix.ver }}
      # Bazel fails if the username is unknown.
      USER: runner
    steps:
      - uses: actions/checkout@v4.2.2
      # Stash the timestamp for the commit SHA that triggered the workflow.
      - run: echo "timestamp=$(git log -1 --pretty=%ct)" >> "${GITHUB_ENV}"
        shell: bash
      - uses: bazel-contrib/setup-bazel@0.15.0
        with:
          bazelisk-version: '1.x'
      - name: Prepare Python ${{ matrix.ver }} environment
        run: |
          "${PYTHON}" -m pip install --upgrade pip
          "${PYTHON}" -m pip install --upgrade setuptools build wheel auditwheel
          "${PYTHON}" -m pip install --upgrade absl-py mypy
          "${PYTHON}" python/toolchains/generate.py
        shell: bash
      - name: Build wheel
        env:
          SOURCE_DATE_EPOCH: ${{ env.timestamp }}
        run: |
          "${PYTHON}" -m build --wheel
          "${PYTHON}" -m auditwheel repair --wheel-dir=. dist/*
        shell: bash
        working-directory: python
      - name: Test wheel
        run: |
          "${PYTHON}" -m pip install google_re2-*.whl
          # Pivot out of the repository so that we test the wheel.
          DIR=$(mktemp -d)
          cp re2_test.py "${DIR}"
          cd "${DIR}"
          "${PYTHON}" re2_test.py
        shell: bash
        working-directory: python
      - uses: actions/upload-artifact@v4.6.2
        with:
          name: ${{ hashFiles('python/google_re2-*.whl') }}
          path: python/google_re2-*.whl
          retention-days: 1
  wheel-macos:
    name: macOS ${{ matrix.os }}, ${{ matrix.arch.name }}, Python ${{ matrix.ver }}
    runs-on: macos-${{ matrix.os }}-large
    strategy:
      fail-fast: false
      matrix:
        arch:
          - { name: X64,   bazel-name: x86_64, python-name: x86_64 }
          - { name: ARM64, bazel-name: arm64,  python-name: arm64  }
        # TODO(rsc): Stop cross-compiling now that we don't use macOS 12.
        # instead, specify `-large` suffix on X64 and `-xlarge` suffix on ARM64.
        os: [13, 14, 15, 26]
        ver: ['3.10', '3.11', '3.12', '3.13', '3.14']
    env:
      BAZELISK_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      BAZEL_CPU: darwin_${{ matrix.arch.bazel-name }}
      PLAT_NAME: macosx-${{ matrix.os }}.0-${{ matrix.arch.python-name }}
      # Force a specific target version of macOS.
      # Otherwise, `delocate` renames the wheels!
      MACOSX_DEPLOYMENT_TARGET: ${{ matrix.os }}.0
      # Stop macOS from reporting the system version as 10.x.
      # Otherwise, Python refuses to install the built wheel!
      SYSTEM_VERSION_COMPAT: 0
    steps:
      - uses: actions/checkout@v4.1.7
      # Stash the timestamp for the commit SHA that triggered the workflow.
      - run: echo "timestamp=$(git log -1 --pretty=%ct)" >> "${GITHUB_ENV}"
        shell: bash
      - uses: bazel-contrib/setup-bazel@0.15.0
        with:
          bazelisk-version: '1.x'
      - uses: actions/setup-python@v5.6.0
        with:
          python-version: ${{ matrix.ver }}
      - name: Prepare Python ${{ matrix.ver }} environment
        run: |
          python -m pip install --upgrade pip
          python -m pip install --upgrade setuptools build wheel delocate
          python -m pip install --upgrade absl-py mypy
          python python/toolchains/generate.py
        shell: bash
      - name: Build wheel
        env:
          SOURCE_DATE_EPOCH: ${{ env.timestamp }}
        run: |
          python -m build --wheel
          python -m delocate.cmd.delocate_wheel --wheel-dir=. dist/*
        shell: bash
        working-directory: python
      - if: matrix.arch.name == runner.arch
        name: Test wheel
        run: |
          python -m pip install google_re2-*.whl
          # Pivot out of the repository so that we test the wheel.
          DIR=$(mktemp -d)
          cp re2_test.py "${DIR}"
          cd "${DIR}"
          python re2_test.py
        shell: bash
        working-directory: python
      - uses: actions/upload-artifact@v4.6.2
        with:
          name: ${{ hashFiles('python/google_re2-*.whl') }}
          path: python/google_re2-*.whl
          retention-days: 1
  wheel-windows:
    name: Windows, ${{ matrix.arch.name }}, Python ${{ matrix.ver }}
    runs-on: ${{ matrix.arch.name == 'ARM64' && 'windows-11-arm' || 'windows-latest' }}
    strategy:
      fail-fast: false
      matrix:
        arch:
          - { name: X86,   bazel-name: x64_x86, python-name: win32 }
          - { name: X64,   bazel-name: x64,     python-name: win_amd64 }
          - { name: ARM64, bazel-name: arm64,   python-name: win_arm64 }
        ver: ['3.10', '3.11', '3.12', '3.13', '3.14']
        exclude:
          - arch: { name: ARM64, bazel-name: arm64, python-name: win_arm64 }
            ver: '3.9'
          - arch: { name: ARM64, bazel-name: arm64, python-name: win_arm64 }
            ver: '3.10'
    env:
      BAZELISK_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      BAZEL_CPU: ${{ matrix.arch.bazel-name }}_windows
      PLAT_NAME: ${{ matrix.arch.python-name }}
    steps:
      - uses: actions/checkout@v4.2.2
      # Stash the timestamp for the commit SHA that triggered the workflow.
      - run: echo "timestamp=$(git log -1 --pretty=%ct)" >> "${GITHUB_ENV}"
        shell: bash
      - uses: bazel-contrib/setup-bazel@0.15.0
        with:
          bazelisk-version: '1.x'
      # Lowercase the architecture name for `actions/setup-python`.
      - run: |
          ARCHITECTURE=${{ matrix.arch.name }}
          echo "architecture=${ARCHITECTURE,,}" >> "${GITHUB_ENV}"
        shell: bash
      - uses: actions/setup-python@v5.6.0
        with:
          python-version: ${{ matrix.ver }}
          architecture: ${{ env.architecture }}
      - name: Prepare Python ${{ matrix.ver }} environment
        run: |
          python -m pip install --upgrade pip
          python -m pip install --upgrade setuptools build wheel delvewheel
          python -m pip install --upgrade absl-py mypy
          python python/toolchains/generate.py
        shell: bash
      - name: Build wheel
        env:
          SOURCE_DATE_EPOCH: ${{ env.timestamp }}
        run: |
          python -m build --wheel
          python -m delvewheel repair --wheel-dir=. dist/*
        shell: bash
        working-directory: python
      - name: Test wheel
        run: |
          python -m pip install google_re2-*.whl
          # Pivot out of the repository so that we test the wheel.
          DIR=$(mktemp -d)
          cp re2_test.py "${DIR}"
          cd "${DIR}"
          python re2_test.py
        shell: bash
        working-directory: python
      - uses: actions/upload-artifact@v4.6.2
        with:
          name: ${{ hashFiles('python/google_re2-*.whl') }}
          path: python/google_re2-*.whl
          retention-days: 1
  publish:
    needs:
      - wheel-linux
      - wheel-macos
      - wheel-windows
    permissions:
      contents: read
      # Required for PyPI publishing.
      id-token: write
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4.2.2
      # Stash the timestamp for the commit SHA that triggered the workflow.
      - run: echo "timestamp=$(git log -1 --pretty=%ct)" >> "${GITHUB_ENV}"
        shell: bash
      - uses: actions/setup-python@v5.6.0
        with:
          python-version: '3.x'
      - name: Prepare Python 3.x environment
        run: |
          python -m pip install --upgrade pip
          python -m pip install --upgrade setuptools build wheel
        shell: bash
      - if: inputs.build <= 1 || inputs.force-sdist == true
        name: Build sdist
        env:
          SOURCE_DATE_EPOCH: ${{ env.timestamp }}
        run: |
          python -m build --sdist
        shell: bash
        working-directory: python
      - uses: actions/download-artifact@v4.3.0
        with:
          path: python
      - name: Set build number to ${{ inputs.build }}
        env:
          SOURCE_DATE_EPOCH: ${{ env.timestamp }}
        run: |
          mkdir -p dist
          for WHL in */google_re2-*.whl; do
            python -m wheel unpack "${WHL}"
            python -m wheel pack --dest-dir=dist --build-number=${{ inputs.build }} google_re2-*
            rm -rf google_re2-*
          done
        shell: bash
        working-directory: python
      - if: inputs.build >= 1
        uses: pypa/gh-action-pypi-publish@v1.13.0
        with:
          packages-dir: python/dist


================================================
FILE: .github/workflows/release-bazel.yml
================================================
name: Release (Bazel)
on:
  # Allow manual triggering from GH UI
  workflow_dispatch:
    inputs:
      tag_name:
        required: true
        type: string
  # Automated trigger from the release.yaml workflow
  workflow_call:
    inputs:
      tag_name:
        required: true
        type: string
    secrets:
      BCR_PUBLISH_TOKEN:
        description: 'Token for pushing to re2-machine/bazel-central-registry'
        required: true
jobs:
  release:
    uses: bazel-contrib/publish-to-bcr/.github/workflows/publish.yaml@v0.2.2
    with:
      draft: false
      tag_name: ${{ inputs.tag_name }}
      registry_fork: re2-machine/bazel-central-registry
      # NOTE: To use attest: true, we need a signed intoto.jsonl file,
      # but that appears to require using
      # the release_ruleset support described on
      # https://github.com/bazel-contrib/publish-to-bcr?tab=readme-ov-file#attesation-support
      # but that requires a release_prep.sh file,
      # and an override on the test command,
      # and may insist on doing the release upload of the source zip
      # (which we do ourselves separately),
      # and possibly more problems I didn't hit because I gave up.
      attest: false # too hard to generate the intoto.jsonl file
    permissions:
      contents: write
      id-token: write
      attestations: write
    secrets:
      # Necessary to push to the BCR fork, and to open a pull request against a registry
      publish_token: ${{ secrets.BCR_PUBLISH_TOKEN }}


================================================
FILE: .github/workflows/release.yml
================================================
name: Release
on:
  push:
    tags: ['2[0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]'] # yyyy-mm-dd
permissions:
  contents: read
jobs:
  create:
    permissions:
      # Required to create the release
      # and upload the release assets.
      contents: write
      # Required for Sigstore signing.
      id-token: write
    runs-on: ubuntu-latest
    env:
      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
    steps:
      - uses: actions/checkout@v4.2.2
      - run: |
          gh release create "${GITHUB_REF_NAME}" \
            --generate-notes --latest --verify-tag \
            --repo "${GITHUB_REPOSITORY}"
          gh release download "${GITHUB_REF_NAME}" \
            --archive tar.gz \
            --repo "${GITHUB_REPOSITORY}"
          gh release download "${GITHUB_REF_NAME}" \
            --archive zip \
            --repo "${GITHUB_REPOSITORY}"
        shell: bash
      - uses: sigstore/gh-action-sigstore-python@v3.0.1
        with:
          # N.B. This is a whitespace-separated string!
          inputs: '*.tar.gz *.zip'
      - run: |
          gh release upload "${GITHUB_REF_NAME}" \
            *.tar.gz *.zip *.sigstore* \
            --repo "${GITHUB_REPOSITORY}"
        shell: bash
  create-bazel:
    needs: create
    uses: ./.github/workflows/release-bazel.yml
    with:
      tag_name: ${{ github.ref_name }}
    permissions:
      contents: write
      id-token: write
      attestations: write
    secrets:
      BCR_PUBLISH_TOKEN: ${{ secrets.BCR_PUBLISH_TOKEN }}


================================================
FILE: .gitignore
================================================
*.pyc
*.orig
core
obj/
benchlog.*
user.bazelrc


================================================
FILE: BUILD.bazel
================================================
# Copyright 2009 The RE2 Authors.  All Rights Reserved.
# Use of this source code is governed by a BSD-style
# license that can be found in the LICENSE file.

# Bazel (http://bazel.build/) BUILD file for RE2.

load("@rules_cc//cc:cc_binary.bzl", "cc_binary")
load("@rules_cc//cc:cc_library.bzl", "cc_library")
load("@rules_cc//cc:cc_test.bzl", "cc_test")

licenses(["notice"])

exports_files(["LICENSE"])

cc_library(
    name = "re2",
    srcs = [
        "re2/bitmap256.cc",
        "re2/bitmap256.h",
        "re2/bitstate.cc",
        "re2/compile.cc",
        "re2/dfa.cc",
        "re2/filtered_re2.cc",
        "re2/mimics_pcre.cc",
        "re2/nfa.cc",
        "re2/onepass.cc",
        "re2/parse.cc",
        "re2/perl_groups.cc",
        "re2/pod_array.h",
        "re2/prefilter.cc",
        "re2/prefilter.h",
        "re2/prefilter_tree.cc",
        "re2/prefilter_tree.h",
        "re2/prog.cc",
        "re2/prog.h",
        "re2/re2.cc",
        "re2/regexp.cc",
        "re2/regexp.h",
        "re2/set.cc",
        "re2/simplify.cc",
        "re2/sparse_array.h",
        "re2/sparse_set.h",
        "re2/tostring.cc",
        "re2/unicode_casefold.cc",
        "re2/unicode_casefold.h",
        "re2/unicode_groups.cc",
        "re2/unicode_groups.h",
        "re2/walker-inl.h",
        "util/rune.cc",
        "util/strutil.cc",
        "util/strutil.h",
        "util/utf.h",
    ],
    hdrs = [
        "re2/filtered_re2.h",
        "re2/re2.h",
        "re2/set.h",
        "re2/stringpiece.h",
    ],
    copts = select({
        # WebAssembly support for threads is... fraught at every level.
        "@platforms//cpu:wasm32": [],
        "@platforms//cpu:wasm64": [],
        "@platforms//os:emscripten": [],
        "@platforms//os:wasi": [],
        "@platforms//os:windows": [],
        "//conditions:default": ["-pthread"],
    }),
    linkopts = select({
        # macOS doesn't need `-pthread' when linking and it appears that
        # older versions of Clang will warn about the unused command line
        # argument, so just don't pass it.
        "@platforms//os:macos": [],
        # WebAssembly support for threads is... fraught at every level.
        "@platforms//cpu:wasm32": [],
        "@platforms//cpu:wasm64": [],
        "@platforms//os:emscripten": [],
        "@platforms//os:wasi": [],
        "@platforms//os:windows": [],
        "//conditions:default": ["-pthread"],
    }),
    visibility = ["//visibility:public"],
    deps = [
        "@abseil-cpp//absl/base",
        "@abseil-cpp//absl/base:core_headers",
        "@abseil-cpp//absl/container:fixed_array",
        "@abseil-cpp//absl/container:flat_hash_map",
        "@abseil-cpp//absl/container:flat_hash_set",
        "@abseil-cpp//absl/container:inlined_vector",
        "@abseil-cpp//absl/hash",
        "@abseil-cpp//absl/log:absl_check",
        "@abseil-cpp//absl/log:absl_log",
        "@abseil-cpp//absl/strings",
        "@abseil-cpp//absl/strings:str_format",
        "@abseil-cpp//absl/synchronization",
        "@abseil-cpp//absl/types:optional",
        "@abseil-cpp//absl/types:span",
    ],
)

cc_library(
    name = "testing",
    testonly = 1,
    srcs = [
        "re2/testing/backtrack.cc",
        "re2/testing/dump.cc",
        "re2/testing/exhaustive_tester.cc",
        "re2/testing/null_walker.cc",
        "re2/testing/regexp_generator.cc",
        "re2/testing/string_generator.cc",
        "re2/testing/tester.cc",
        "util/pcre.cc",
    ],
    hdrs = [
        "re2/testing/exhaustive_tester.h",
        "re2/testing/regexp_generator.h",
        "re2/testing/string_generator.h",
        "re2/testing/tester.h",
        "util/malloc_counter.h",
        "util/pcre.h",

        # Exposed for testing only.
        "re2/bitmap256.h",
        "re2/pod_array.h",
        "re2/prefilter.h",
        "re2/prefilter_tree.h",
        "re2/prog.h",
        "re2/regexp.h",
        "re2/sparse_array.h",
        "re2/sparse_set.h",
        "re2/unicode_casefold.h",
        "re2/unicode_groups.h",
        "re2/walker-inl.h",
        "util/strutil.h",
        "util/utf.h",
    ],
    visibility = [":__subpackages__"],
    deps = [
        ":re2",
        "@abseil-cpp//absl/base",
        "@abseil-cpp//absl/base:core_headers",
        "@abseil-cpp//absl/container:flat_hash_set",
        "@abseil-cpp//absl/flags:flag",
        "@abseil-cpp//absl/log:absl_check",
        "@abseil-cpp//absl/log:absl_log",
        "@abseil-cpp//absl/strings",
        "@abseil-cpp//absl/strings:str_format",
        "@googletest//:gtest",
    ],
)

cc_test(
    name = "charclass_test",
    size = "small",
    srcs = ["re2/testing/charclass_test.cc"],
    deps = [
        ":testing",
        "@abseil-cpp//absl/base:core_headers",
        "@abseil-cpp//absl/strings:str_format",
        "@googletest//:gtest",
        "@googletest//:gtest_main",
    ],
)

cc_test(
    name = "compile_test",
    size = "small",
    srcs = ["re2/testing/compile_test.cc"],
    deps = [
        ":testing",
        "@abseil-cpp//absl/base:core_headers",
        "@abseil-cpp//absl/log:absl_check",
        "@abseil-cpp//absl/log:absl_log",
        "@abseil-cpp//absl/strings",
        "@googletest//:gtest",
        "@googletest//:gtest_main",
    ],
)

cc_test(
    name = "filtered_re2_test",
    size = "small",
    srcs = ["re2/testing/filtered_re2_test.cc"],
    deps = [
        ":re2",
        ":testing",
        "@abseil-cpp//absl/base:core_headers",
        "@abseil-cpp//absl/log:absl_check",
        "@abseil-cpp//absl/log:absl_log",
        "@googletest//:gtest",
        "@googletest//:gtest_main",
    ],
)

cc_test(
    name = "mimics_pcre_test",
    size = "small",
    srcs = ["re2/testing/mimics_pcre_test.cc"],
    deps = [
        ":testing",
        "@abseil-cpp//absl/base:core_headers",
        "@abseil-cpp//absl/log:absl_check",
        "@abseil-cpp//absl/log:absl_log",
        "@googletest//:gtest",
        "@googletest//:gtest_main",
    ],
)

cc_test(
    name = "parse_test",
    size = "small",
    srcs = ["re2/testing/parse_test.cc"],
    deps = [
        ":testing",
        "@abseil-cpp//absl/base:core_headers",
        "@abseil-cpp//absl/log:absl_check",
        "@abseil-cpp//absl/log:absl_log",
        "@googletest//:gtest",
        "@googletest//:gtest_main",
    ],
)

cc_test(
    name = "possible_match_test",
    size = "small",
    srcs = ["re2/testing/possible_match_test.cc"],
    deps = [
        ":re2",
        ":testing",
        "@abseil-cpp//absl/base:core_headers",
        "@abseil-cpp//absl/log:absl_check",
        "@abseil-cpp//absl/log:absl_log",
        "@abseil-cpp//absl/strings",
        "@googletest//:gtest",
        "@googletest//:gtest_main",
    ],
)

cc_test(
    name = "re2_arg_test",
    size = "small",
    srcs = ["re2/testing/re2_arg_test.cc"],
    deps = [
        ":re2",
        ":testing",
        "@abseil-cpp//absl/base:core_headers",
        "@abseil-cpp//absl/log:absl_check",
        "@abseil-cpp//absl/log:absl_log",
        "@abseil-cpp//absl/types:optional",
        "@googletest//:gtest",
        "@googletest//:gtest_main",
    ],
)

cc_test(
    name = "re2_test",
    size = "small",
    srcs = ["re2/testing/re2_test.cc"],
    deps = [
        ":re2",
        ":testing",
        "@abseil-cpp//absl/base:core_headers",
        "@abseil-cpp//absl/log:absl_check",
        "@abseil-cpp//absl/log:absl_log",
        "@abseil-cpp//absl/strings",
        "@abseil-cpp//absl/strings:str_format",
        "@googletest//:gtest",
        "@googletest//:gtest_main",
    ],
)

cc_test(
    name = "regexp_test",
    size = "small",
    srcs = ["re2/testing/regexp_test.cc"],
    deps = [
        ":testing",
        "@abseil-cpp//absl/log:absl_check",
        "@abseil-cpp//absl/log:absl_log",
        "@googletest//:gtest",
        "@googletest//:gtest_main",
    ],
)

cc_test(
    name = "required_prefix_test",
    size = "small",
    srcs = ["re2/testing/required_prefix_test.cc"],
    deps = [
        ":testing",
        "@abseil-cpp//absl/base:core_headers",
        "@abseil-cpp//absl/log:absl_check",
        "@abseil-cpp//absl/log:absl_log",
        "@googletest//:gtest",
        "@googletest//:gtest_main",
    ],
)

cc_test(
    name = "search_test",
    size = "small",
    srcs = ["re2/testing/search_test.cc"],
    deps = [
        ":testing",
        "@abseil-cpp//absl/base:core_headers",
        "@googletest//:gtest",
        "@googletest//:gtest_main",
    ],
)

cc_test(
    name = "set_test",
    size = "small",
    srcs = ["re2/testing/set_test.cc"],
    deps = [
        ":re2",
        ":testing",
        "@abseil-cpp//absl/log:absl_check",
        "@abseil-cpp//absl/log:absl_log",
        "@googletest//:gtest",
        "@googletest//:gtest_main",
    ],
)

cc_test(
    name = "simplify_test",
    size = "small",
    srcs = ["re2/testing/simplify_test.cc"],
    deps = [
        ":testing",
        "@abseil-cpp//absl/base:core_headers",
        "@abseil-cpp//absl/log:absl_check",
        "@abseil-cpp//absl/log:absl_log",
        "@googletest//:gtest",
        "@googletest//:gtest_main",
    ],
)

cc_test(
    name = "string_generator_test",
    size = "small",
    srcs = ["re2/testing/string_generator_test.cc"],
    deps = [
        ":testing",
        "@abseil-cpp//absl/strings",
        "@googletest//:gtest",
        "@googletest//:gtest_main",
    ],
)

cc_test(
    name = "dfa_test",
    size = "large",
    srcs = ["re2/testing/dfa_test.cc"],
    deps = [
        ":re2",
        ":testing",
        "@abseil-cpp//absl/base:core_headers",
        "@abseil-cpp//absl/flags:flag",
        "@abseil-cpp//absl/log:absl_check",
        "@abseil-cpp//absl/log:absl_log",
        "@abseil-cpp//absl/strings",
        "@abseil-cpp//absl/strings:str_format",
        "@googletest//:gtest",
        "@googletest//:gtest_main",
    ],
)

cc_test(
    name = "exhaustive1_test",
    size = "large",
    srcs = ["re2/testing/exhaustive1_test.cc"],
    deps = [
        ":testing",
        "@googletest//:gtest",
        "@googletest//:gtest_main",
    ],
)

cc_test(
    name = "exhaustive2_test",
    size = "large",
    srcs = ["re2/testing/exhaustive2_test.cc"],
    deps = [
        ":testing",
        "@googletest//:gtest",
        "@googletest//:gtest_main",
    ],
)

cc_test(
    name = "exhaustive3_test",
    size = "large",
    srcs = ["re2/testing/exhaustive3_test.cc"],
    deps = [
        ":testing",
        "@googletest//:gtest",
        "@googletest//:gtest_main",
    ],
)

cc_test(
    name = "exhaustive_test",
    size = "large",
    srcs = ["re2/testing/exhaustive_test.cc"],
    deps = [
        ":testing",
        "@googletest//:gtest",
        "@googletest//:gtest_main",
    ],
)

cc_test(
    name = "random_test",
    size = "large",
    srcs = ["re2/testing/random_test.cc"],
    deps = [
        ":testing",
        "@abseil-cpp//absl/flags:flag",
        "@abseil-cpp//absl/strings:str_format",
        "@googletest//:gtest",
        "@googletest//:gtest_main",
    ],
)

cc_binary(
    name = "regexp_benchmark",
    testonly = 1,
    srcs = ["re2/testing/regexp_benchmark.cc"],
    deps = [
        ":re2",
        ":testing",
        "@abseil-cpp//absl/container:flat_hash_map",
        "@abseil-cpp//absl/flags:flag",
        "@abseil-cpp//absl/log:absl_check",
        "@abseil-cpp//absl/log:absl_log",
        "@abseil-cpp//absl/strings",
        "@abseil-cpp//absl/strings:str_format",
        "@abseil-cpp//absl/synchronization",
        "@google_benchmark//:benchmark_main",
    ],
)

test_suite(
    name = "small_tests",
    tags = ["small"],
    tests = [
        ":charclass_test",
        ":compile_test",
        ":filtered_re2_test",
        ":mimics_pcre_test",
        ":parse_test",
        ":possible_match_test",
        ":re2_arg_test",
        ":re2_test",
        ":regexp_test",
        ":required_prefix_test",
        ":search_test",
        ":set_test",
        ":simplify_test",
        ":string_generator_test",
    ],
)


================================================
FILE: CMakeLists.txt
================================================
# Copyright 2015 The RE2 Authors.  All Rights Reserved.
# Use of this source code is governed by a BSD-style
# license that can be found in the LICENSE file.

# https://github.com/google/oss-policies-info/blob/main/foundational-cxx-support-matrix.md
cmake_minimum_required(VERSION 3.22)

project(RE2 CXX)
include(CMakePackageConfigHelpers)
include(CTest)
include(GNUInstallDirs)

set(RE2_CXX_VERSION cxx_std_17)

option(BUILD_SHARED_LIBS "build shared libraries" OFF)
option(RE2_USE_ICU "build against ICU for full Unicode properties support" OFF)

# For historical reasons, this is just "USEPCRE", not "RE2_USE_PCRE".
option(USEPCRE "build against PCRE for testing and benchmarking" OFF)

# See https://groups.google.com/g/re2-dev/c/P6_NM0YIWvA for details.
# This has no effect unless RE2 is being built for an Apple platform
# such as macOS or iOS.
option(RE2_BUILD_FRAMEWORK "build RE2 as a framework" OFF)

# CMake seems to have no way to enable/disable testing per subproject,
# so we provide an option similar to BUILD_TESTING, but just for RE2.
# RE2_BUILD_TESTING builds and runs tests, and builds benchmarks
# RE2_TEST and RE2_BENCHMARK provide more fine-grained control.
option(RE2_TEST "build and run RE2 tests" OFF)
option(RE2_BENCHMARK "build RE2 benchmarks" OFF)
option(RE2_BUILD_TESTING "build and run RE2 tests; build RE2 benchmarks" OFF)

# RE2_INSTALL (which defaults to ON) controls whether the installation
# rules are generated.
option(RE2_INSTALL "install RE2" ON)

# The pkg-config Requires: field.
set(REQUIRES)

# ABI version
# http://tldp.org/HOWTO/Program-Library-HOWTO/shared-libraries.html
set(SONAME 11)

set(EXTRA_TARGET_LINK_LIBRARIES)

if(MSVC)
  if(MSVC_VERSION LESS 1920)
    message(FATAL_ERROR "you need Visual Studio 2019 or later")
  endif()
  if(BUILD_SHARED_LIBS)
    set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
  endif()
  # CMake defaults to /W3, but some users like /W4 (or /Wall) and /WX,
  # so we disable various warnings that aren't particularly helpful.
  add_compile_options(/wd4100 /wd4201 /wd4456 /wd4457 /wd4702 /wd4815)
  # Without a byte order mark (BOM), Visual Studio assumes that the source
  # file is encoded using the current user code page, so we specify UTF-8.
  add_compile_options(/utf-8)
endif()

if(WIN32)
  add_definitions(-DUNICODE -D_UNICODE -DSTRICT -DNOMINMAX)
  add_definitions(-D_CRT_SECURE_NO_WARNINGS -D_SCL_SECURE_NO_WARNINGS)
endif()

if(UNIX)
  set(THREADS_PREFER_PTHREAD_FLAG ON)
  find_package(Threads REQUIRED)
endif()

set(ABSL_DEPS
    absl_absl_check
    absl_absl_log
    absl_base
    absl_core_headers
    absl_fixed_array
    absl_flags
    absl_flat_hash_map
    absl_flat_hash_set
    absl_hash
    absl_inlined_vector
    absl_optional
    absl_span
    absl_str_format
    absl_strings
    absl_synchronization
    )

# If a top-level project has called add_directory(abseil-cpp) already (possibly
# indirectly), let that take precedence over any copy of Abseil that might have
# been installed on the system. And likewise for ICU, GoogleTest and Benchmark.
if(NOT TARGET absl::base)
  find_package(absl REQUIRED)
endif()
list(APPEND REQUIRES ${ABSL_DEPS})

if(RE2_USE_ICU)
  if(NOT TARGET ICU::uc)
    find_package(ICU REQUIRED COMPONENTS uc)
  endif()
  add_definitions(-DRE2_USE_ICU)
  list(APPEND REQUIRES icu-uc)
endif()

if(USEPCRE)
  add_definitions(-DUSEPCRE)
  list(APPEND EXTRA_TARGET_LINK_LIBRARIES pcre)
endif()

list(JOIN REQUIRES " " REQUIRES)

set(RE2_SOURCES
    re2/bitmap256.cc
    re2/bitstate.cc
    re2/compile.cc
    re2/dfa.cc
    re2/filtered_re2.cc
    re2/mimics_pcre.cc
    re2/nfa.cc
    re2/onepass.cc
    re2/parse.cc
    re2/perl_groups.cc
    re2/prefilter.cc
    re2/prefilter_tree.cc
    re2/prog.cc
    re2/re2.cc
    re2/regexp.cc
    re2/set.cc
    re2/simplify.cc
    re2/tostring.cc
    re2/unicode_casefold.cc
    re2/unicode_groups.cc
    util/rune.cc
    util/strutil.cc
    )

set(RE2_HEADERS
    re2/filtered_re2.h
    re2/re2.h
    re2/set.h
    re2/stringpiece.h
    )

add_library(re2 ${RE2_SOURCES})
target_compile_features(re2 PUBLIC ${RE2_CXX_VERSION})
target_include_directories(re2 PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>)
# CMake gives "set_target_properties called with incorrect number of arguments."
# errors if we don't quote ${RE2_HEADERS}, so quote it despite prevailing style.
set_target_properties(re2 PROPERTIES PUBLIC_HEADER "${RE2_HEADERS}")
set_target_properties(re2 PROPERTIES SOVERSION ${SONAME} VERSION ${SONAME}.0.0)
add_library(re2::re2 ALIAS re2)

if(APPLE AND RE2_BUILD_FRAMEWORK)
  set_target_properties(re2 PROPERTIES
                        FRAMEWORK TRUE
                        FRAMEWORK_VERSION A
                        MACOSX_FRAMEWORK_IDENTIFIER com.googlesource.code.re2)
endif()

if(UNIX)
  target_link_libraries(re2 PUBLIC Threads::Threads)
endif()

foreach(dep ${ABSL_DEPS})
  # Work around https://gitlab.kitware.com/cmake/cmake/-/issues/16899. >:(
  string(PREPEND dep "^")
  string(REGEX REPLACE "\\^absl_" "absl::" dep ${dep})
  target_link_libraries(re2 PUBLIC ${dep})
endforeach()

if(RE2_USE_ICU)
  target_link_libraries(re2 PUBLIC ICU::uc)
endif()

if(RE2_BUILD_TESTING OR RE2_TEST OR RE2_BENCHMARK)
  set(TESTING_SOURCES
      re2/testing/backtrack.cc
      re2/testing/dump.cc
      re2/testing/exhaustive_tester.cc
      re2/testing/null_walker.cc
      re2/testing/regexp_generator.cc
      re2/testing/string_generator.cc
      re2/testing/tester.cc
      util/pcre.cc
      )

  add_library(testing ${TESTING_SOURCES})
  if(BUILD_SHARED_LIBS AND WIN32)
    target_compile_definitions(testing PRIVATE -DRE2_BUILD_TESTING_DLL)
  endif()
  target_compile_features(testing PUBLIC ${RE2_CXX_VERSION})
  target_link_libraries(testing PUBLIC re2 GTest::gtest)

  if(RE2_BUILD_TESTING OR RE2_TEST)
    if(NOT TARGET GTest::gtest)
      find_package(GTest REQUIRED)
    endif()

    set(TEST_TARGETS
        charclass_test
        compile_test
        filtered_re2_test
        mimics_pcre_test
        parse_test
        possible_match_test
        re2_test
        re2_arg_test
        regexp_test
        required_prefix_test
        search_test
        set_test
        simplify_test
        string_generator_test

        dfa_test
        exhaustive1_test
        exhaustive2_test
        exhaustive3_test
        exhaustive_test
        random_test
        )

    foreach(target ${TEST_TARGETS})
      add_executable(${target} re2/testing/${target}.cc)
      if(BUILD_SHARED_LIBS AND WIN32)
        target_compile_definitions(${target} PRIVATE -DRE2_CONSUME_TESTING_DLL)
      endif()
      target_compile_features(${target} PUBLIC ${RE2_CXX_VERSION})
      target_link_libraries(${target} PUBLIC re2 testing GTest::gtest_main ${EXTRA_TARGET_LINK_LIBRARIES})
      add_test(NAME ${target} COMMAND ${target})
    endforeach()
  endif()

  if(RE2_BUILD_TESTING OR RE2_BENCHMARK)
    if(NOT TARGET benchmark::benchmark)
      find_package(benchmark REQUIRED)
    endif()
    set(BENCHMARK_TARGETS
        regexp_benchmark
        )
    foreach(target ${BENCHMARK_TARGETS})
      add_executable(${target} re2/testing/${target}.cc)
      if(BUILD_SHARED_LIBS AND WIN32)
        target_compile_definitions(${target} PRIVATE -DRE2_CONSUME_TESTING_DLL)
      endif()
      target_compile_features(${target} PUBLIC ${RE2_CXX_VERSION})
      target_link_libraries(${target} PUBLIC testing re2 benchmark::benchmark_main ${EXTRA_TARGET_LINK_LIBRARIES})
    endforeach()
  endif()
endif()

if(RE2_INSTALL)
  install(TARGETS re2
          EXPORT re2Targets
          ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
          LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
          RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
          FRAMEWORK DESTINATION ${CMAKE_INSTALL_LIBDIR}
          PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/re2
          INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
  install(EXPORT re2Targets
          DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/re2
          NAMESPACE re2::)

  configure_package_config_file(${CMAKE_CURRENT_SOURCE_DIR}/re2Config.cmake.in
                                ${CMAKE_CURRENT_BINARY_DIR}/re2Config.cmake
                                INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/re2)
  write_basic_package_version_file(${CMAKE_CURRENT_BINARY_DIR}/re2ConfigVersion.cmake
                                   VERSION ${SONAME}.0.0
                                   COMPATIBILITY SameMajorVersion)

  install(FILES ${CMAKE_CURRENT_BINARY_DIR}/re2Config.cmake
                ${CMAKE_CURRENT_BINARY_DIR}/re2ConfigVersion.cmake
          DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/re2)

  configure_file(${CMAKE_CURRENT_SOURCE_DIR}/re2.pc.in
                 ${CMAKE_CURRENT_BINARY_DIR}/re2.pc
                 @ONLY)

  install(FILES ${CMAKE_CURRENT_BINARY_DIR}/re2.pc
          DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
endif()


================================================
FILE: CONTRIBUTING.md
================================================
See the [Contribute](https://github.com/google/re2/wiki/Contribute) wiki page.


================================================
FILE: LICENSE
================================================
// Copyright (c) 2009 The RE2 Authors. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//    * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//    * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//    * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.


================================================
FILE: MODULE.bazel
================================================
# Copyright 2009 The RE2 Authors.  All Rights Reserved.
# Use of this source code is governed by a BSD-style
# license that can be found in the LICENSE file.

# Bazel (http://bazel.build/) MODULE file for RE2.

module(
    name = "re2",
    version = "2025-11-05",
    compatibility_level = 1,
)

bazel_dep(name = "platforms", version = "1.0.0")
bazel_dep(name = "apple_support", version = "1.24.2")
bazel_dep(name = "rules_cc", version = "0.2.14")
bazel_dep(name = "abseil-cpp", version = "20250814.1")
bazel_dep(name = "rules_python", version = "1.7.0")
bazel_dep(name = "pybind11_bazel", version = "3.0.0")

# This is a temporary hack for `x64_x86_windows`.
# TODO(junyer): Remove whenever no longer needed.
cc_configure = use_extension("@rules_cc//cc:extensions.bzl", "cc_configure_extension", dev_dependency = True)
use_repo(cc_configure, "local_config_cc")

# These dependencies will be ignored when the `re2` module is not
# the root module (or when `--ignore_dev_dependency` is enabled).
bazel_dep(name = "google_benchmark", version = "1.9.4", dev_dependency = True)
bazel_dep(name = "googletest", version = "1.17.0.bcr.2", dev_dependency = True)
bazel_dep(name = "abseil-py", version = "2.1.0", dev_dependency = True)


================================================
FILE: Makefile
================================================
# Copyright 2009 The RE2 Authors.  All Rights Reserved.
# Use of this source code is governed by a BSD-style
# license that can be found in the LICENSE file.

# Build against Abseil.
ABSL_DEPS=\
	absl_absl_check\
	absl_absl_log\
	absl_base\
	absl_core_headers\
	absl_fixed_array\
	absl_flags\
	absl_flat_hash_map\
	absl_flat_hash_set\
	absl_hash\
	absl_inlined_vector\
	absl_optional\
	absl_span\
	absl_str_format\
	absl_strings\
	absl_synchronization\

PKG_CONFIG?=pkg-config
CCABSL=$(shell $(PKG_CONFIG) $(ABSL_DEPS) --cflags)
# GCC barfs on `-Wl` whereas Clang doesn't mind, but it's unclear what
# causes it to manifest on Ubuntu 22.04 LTS, so filter it out for now.
# Similar is needed for `static-testinstall` and `shared-testinstall`.
LDABSL=$(shell $(PKG_CONFIG) $(ABSL_DEPS) --libs | sed -e 's/-Wl / /g')

# To build against ICU for full Unicode properties support,
# uncomment the next two lines:
# CCICU=$(shell $(PKG_CONFIG) icu-uc --cflags) -DRE2_USE_ICU
# LDICU=$(shell $(PKG_CONFIG) icu-uc --libs)

# Build against GoogleTest and Benchmark for... testing and benchmarking.
# Capture only the `-L` flags for now; we will pass the `-l` flags later.
CCGTEST=$(shell $(PKG_CONFIG) gtest gtest_main --cflags)
LDGTEST=$(shell $(PKG_CONFIG) gtest gtest_main --libs-only-L)
CCBENCHMARK=$(shell $(PKG_CONFIG) benchmark --cflags)
LDBENCHMARK=$(shell $(PKG_CONFIG) benchmark --libs-only-L)

# To build against PCRE for testing and benchmarking,
# uncomment the next two lines:
# CCPCRE=-I/usr/local/include -DUSEPCRE
# LDPCRE=-L/usr/local/lib -lpcre

CXX?=g++
# can override
CXXFLAGS?=-O3 -g
LDFLAGS?=
# required
RE2_CXXFLAGS?=-std=c++17 -pthread -Wall -Wextra -Wno-unused-parameter -Wno-missing-field-initializers -I. $(CCABSL) $(CCICU) $(CCGTEST) $(CCBENCHMARK) $(CCPCRE)
RE2_LDFLAGS?=-pthread $(LDABSL) $(LDICU) $(LDGTEST) $(LDBENCHMARK) $(LDPCRE)
AR?=ar
ARFLAGS?=rsc
NM?=nm
NMFLAGS?=-p

# Variables mandated by GNU, the arbiter of all good taste on the internet.
# http://www.gnu.org/prep/standards/standards.html
prefix=/usr/local
exec_prefix=$(prefix)
includedir=$(prefix)/include
libdir=$(exec_prefix)/lib
INSTALL=install
INSTALL_DATA=$(INSTALL) -m 644

# Work around the weirdness of sed(1) on Darwin. :/
ifeq ($(shell uname),Darwin)
SED_INPLACE=sed -i ''
else ifeq ($(shell uname),SunOS)
SED_INPLACE=sed -i
else
SED_INPLACE=sed -i
endif

# The pkg-config Requires: field.
REQUIRES=$(ABSL_DEPS)
ifdef LDICU
REQUIRES+=icu-uc
endif

# ABI version
# http://tldp.org/HOWTO/Program-Library-HOWTO/shared-libraries.html
SONAME=11

# To rebuild the Tables generated by Perl and Python scripts (requires Internet
# access for Unicode data), uncomment the following line:
# REBUILD_TABLES=1

# The SunOS linker does not support wildcards. :(
ifeq ($(shell uname),Darwin)
SOEXT=dylib
SOEXTVER=$(SONAME).$(SOEXT)
SOEXTVER00=$(SONAME).0.0.$(SOEXT)
MAKE_SHARED_LIBRARY=$(CXX) -dynamiclib -Wl,-compatibility_version,$(SONAME),-current_version,$(SONAME).0.0,-install_name,$(libdir)/libre2.$(SOEXTVER),-exported_symbols_list,libre2.symbols.darwin
else ifeq ($(shell uname),SunOS)
SOEXT=so
SOEXTVER=$(SOEXT).$(SONAME)
SOEXTVER00=$(SOEXT).$(SONAME).0.0
MAKE_SHARED_LIBRARY=$(CXX) -shared -Wl,-soname,libre2.$(SOEXTVER)
else
SOEXT=so
SOEXTVER=$(SOEXT).$(SONAME)
SOEXTVER00=$(SOEXT).$(SONAME).0.0
MAKE_SHARED_LIBRARY=$(CXX) -shared -Wl,-soname,libre2.$(SOEXTVER),--version-script,libre2.symbols
endif

.PHONY: all
all: obj/libre2.a obj/so/libre2.$(SOEXT)

INSTALL_HFILES=\
	re2/filtered_re2.h\
	re2/re2.h\
	re2/set.h\
	re2/stringpiece.h\

HFILES=\
	util/malloc_counter.h\
	util/pcre.h\
	util/strutil.h\
	util/utf.h\
	re2/bitmap256.h\
	re2/filtered_re2.h\
	re2/pod_array.h\
	re2/prefilter.h\
	re2/prefilter_tree.h\
	re2/prog.h\
	re2/re2.h\
	re2/regexp.h\
	re2/set.h\
	re2/sparse_array.h\
	re2/sparse_set.h\
	re2/stringpiece.h\
	re2/testing/exhaustive_tester.h\
	re2/testing/regexp_generator.h\
	re2/testing/string_generator.h\
	re2/testing/tester.h\
	re2/unicode_casefold.h\
	re2/unicode_groups.h\
	re2/walker-inl.h\

OFILES=\
	obj/util/rune.o\
	obj/util/strutil.o\
	obj/re2/bitmap256.o\
	obj/re2/bitstate.o\
	obj/re2/compile.o\
	obj/re2/dfa.o\
	obj/re2/filtered_re2.o\
	obj/re2/mimics_pcre.o\
	obj/re2/nfa.o\
	obj/re2/onepass.o\
	obj/re2/parse.o\
	obj/re2/perl_groups.o\
	obj/re2/prefilter.o\
	obj/re2/prefilter_tree.o\
	obj/re2/prog.o\
	obj/re2/re2.o\
	obj/re2/regexp.o\
	obj/re2/set.o\
	obj/re2/simplify.o\
	obj/re2/tostring.o\
	obj/re2/unicode_casefold.o\
	obj/re2/unicode_groups.o\

TESTOFILES=\
	obj/util/pcre.o\
	obj/re2/testing/backtrack.o\
	obj/re2/testing/dump.o\
	obj/re2/testing/exhaustive_tester.o\
	obj/re2/testing/null_walker.o\
	obj/re2/testing/regexp_generator.o\
	obj/re2/testing/string_generator.o\
	obj/re2/testing/tester.o\

TESTS=\
	obj/test/charclass_test\
	obj/test/compile_test\
	obj/test/filtered_re2_test\
	obj/test/mimics_pcre_test\
	obj/test/parse_test\
	obj/test/possible_match_test\
	obj/test/re2_test\
	obj/test/re2_arg_test\
	obj/test/regexp_test\
	obj/test/required_prefix_test\
	obj/test/search_test\
	obj/test/set_test\
	obj/test/simplify_test\
	obj/test/string_generator_test\

BIGTESTS=\
	obj/test/dfa_test\
	obj/test/exhaustive1_test\
	obj/test/exhaustive2_test\
	obj/test/exhaustive3_test\
	obj/test/exhaustive_test\
	obj/test/random_test\

SOFILES=$(patsubst obj/%,obj/so/%,$(OFILES))
# We use TESTOFILES for testing the shared lib, only it is built differently.
STESTS=$(patsubst obj/%,obj/so/%,$(TESTS))
SBIGTESTS=$(patsubst obj/%,obj/so/%,$(BIGTESTS))

DOFILES=$(patsubst obj/%,obj/dbg/%,$(OFILES))
DTESTOFILES=$(patsubst obj/%,obj/dbg/%,$(TESTOFILES))
DTESTS=$(patsubst obj/%,obj/dbg/%,$(TESTS))
DBIGTESTS=$(patsubst obj/%,obj/dbg/%,$(BIGTESTS))

.PRECIOUS: obj/%.o
obj/%.o: %.cc $(HFILES)
	@mkdir -p $$(dirname $@)
	$(CXX) -c -o $@ $(CPPFLAGS) $(RE2_CXXFLAGS) $(CXXFLAGS) -DNDEBUG $*.cc

.PRECIOUS: obj/dbg/%.o
obj/dbg/%.o: %.cc $(HFILES)
	@mkdir -p $$(dirname $@)
	$(CXX) -c -o $@ $(CPPFLAGS) $(RE2_CXXFLAGS) $(CXXFLAGS) $*.cc

.PRECIOUS: obj/so/%.o
obj/so/%.o: %.cc $(HFILES)
	@mkdir -p $$(dirname $@)
	$(CXX) -c -o $@ -fPIC $(CPPFLAGS) $(RE2_CXXFLAGS) $(CXXFLAGS) -DNDEBUG $*.cc

.PRECIOUS: obj/libre2.a
obj/libre2.a: $(OFILES)
	@mkdir -p obj
	$(AR) $(ARFLAGS) obj/libre2.a $(OFILES)

.PRECIOUS: obj/dbg/libre2.a
obj/dbg/libre2.a: $(DOFILES)
	@mkdir -p obj/dbg
	$(AR) $(ARFLAGS) obj/dbg/libre2.a $(DOFILES)

.PRECIOUS: obj/so/libre2.$(SOEXT)
obj/so/libre2.$(SOEXT): $(SOFILES) libre2.symbols libre2.symbols.darwin
	@mkdir -p obj/so
	$(MAKE_SHARED_LIBRARY) -o obj/so/libre2.$(SOEXTVER) $(SOFILES) $(RE2_LDFLAGS) $(LDFLAGS)
	ln -sf libre2.$(SOEXTVER) $@

.PRECIOUS: obj/dbg/test/%
obj/dbg/test/%: obj/dbg/libre2.a obj/dbg/re2/testing/%.o $(DTESTOFILES)
	@mkdir -p obj/dbg/test
	$(CXX) -o $@ obj/dbg/re2/testing/$*.o $(DTESTOFILES) obj/dbg/libre2.a $(RE2_LDFLAGS) $(LDFLAGS) -lgtest -lgtest_main

.PRECIOUS: obj/test/%
obj/test/%: obj/libre2.a obj/re2/testing/%.o $(TESTOFILES)
	@mkdir -p obj/test
	$(CXX) -o $@ obj/re2/testing/$*.o $(TESTOFILES) obj/libre2.a $(RE2_LDFLAGS) $(LDFLAGS) -lgtest -lgtest_main

# Test the shared lib, falling back to the static lib for private symbols
.PRECIOUS: obj/so/test/%
obj/so/test/%: obj/so/libre2.$(SOEXT) obj/libre2.a obj/re2/testing/%.o $(TESTOFILES)
	@mkdir -p obj/so/test
	$(CXX) -o $@ obj/re2/testing/$*.o $(TESTOFILES) -Lobj/so -lre2 obj/libre2.a $(RE2_LDFLAGS) $(LDFLAGS) -lgtest -lgtest_main

obj/test/regexp_benchmark: obj/libre2.a obj/re2/testing/regexp_benchmark.o $(TESTOFILES)
	@mkdir -p obj/test
	$(CXX) -o $@ obj/re2/testing/regexp_benchmark.o $(TESTOFILES) obj/libre2.a $(RE2_LDFLAGS) $(LDFLAGS) -lgtest -lbenchmark -lbenchmark_main

obj/test/re2_fuzzer: obj/libre2.a obj/re2/fuzzing/re2_fuzzer.o
	@mkdir -p obj/test
	$(CXX) -o $@ obj/re2/fuzzing/re2_fuzzer.o obj/libre2.a $(RE2_LDFLAGS) $(LDFLAGS)

ifdef REBUILD_TABLES
.PRECIOUS: re2/perl_groups.cc
re2/perl_groups.cc: re2/make_perl_groups.pl
	perl $< > $@

.PRECIOUS: re2/unicode_%.cc
re2/unicode_%.cc: re2/make_unicode_%.py re2/unicode.py
	python3 $< > $@
endif

.PHONY: distclean
distclean: clean
	rm -f re2/perl_groups.cc re2/unicode_casefold.cc re2/unicode_groups.cc

.PHONY: clean
clean:
	rm -rf obj
	rm -f re2/*.pyc

.PHONY: testofiles
testofiles: $(TESTOFILES)

.PHONY: test
test: $(DTESTS) $(TESTS) $(STESTS) debug-test static-test shared-test

.PHONY: debug-test
debug-test: $(DTESTS)
	@./runtests $(DTESTS)

.PHONY: static-test
static-test: $(TESTS)
	@./runtests $(TESTS)

.PHONY: shared-test
shared-test: $(STESTS)
	@./runtests -shared-library-path obj/so $(STESTS)

.PHONY: debug-bigtest
debug-bigtest: $(DTESTS) $(DBIGTESTS)
	@./runtests $(DTESTS) $(DBIGTESTS)

.PHONY: static-bigtest
static-bigtest: $(TESTS) $(BIGTESTS)
	@./runtests $(TESTS) $(BIGTESTS)

.PHONY: shared-bigtest
shared-bigtest: $(STESTS) $(SBIGTESTS)
	@./runtests -shared-library-path obj/so $(STESTS) $(SBIGTESTS)

.PHONY: benchmark
benchmark: obj/test/regexp_benchmark

.PHONY: fuzz
fuzz: obj/test/re2_fuzzer

.PHONY: install
install: static-install shared-install

.PHONY: static
static: obj/libre2.a

.PHONY: static-install
static-install: obj/libre2.a common-install
	$(INSTALL) obj/libre2.a $(DESTDIR)$(libdir)/libre2.a

.PHONY: shared
shared: obj/so/libre2.$(SOEXT)

.PHONY: shared-install
shared-install: obj/so/libre2.$(SOEXT) common-install
	$(INSTALL) obj/so/libre2.$(SOEXT) $(DESTDIR)$(libdir)/libre2.$(SOEXTVER00)
	ln -sf libre2.$(SOEXTVER00) $(DESTDIR)$(libdir)/libre2.$(SOEXTVER)
	ln -sf libre2.$(SOEXTVER00) $(DESTDIR)$(libdir)/libre2.$(SOEXT)

.PHONY: common-install
common-install:
	mkdir -p $(DESTDIR)$(includedir)/re2 $(DESTDIR)$(libdir)/pkgconfig
	$(INSTALL_DATA) $(INSTALL_HFILES) $(DESTDIR)$(includedir)/re2
	$(INSTALL_DATA) re2.pc.in $(DESTDIR)$(libdir)/pkgconfig/re2.pc
	$(SED_INPLACE) -e "s#@CMAKE_INSTALL_FULL_INCLUDEDIR@#$(includedir)#" $(DESTDIR)$(libdir)/pkgconfig/re2.pc
	$(SED_INPLACE) -e "s#@CMAKE_INSTALL_FULL_LIBDIR@#$(libdir)#" $(DESTDIR)$(libdir)/pkgconfig/re2.pc
	$(SED_INPLACE) -e "s#@REQUIRES@#$(REQUIRES)#" $(DESTDIR)$(libdir)/pkgconfig/re2.pc
	$(SED_INPLACE) -e "s#@SONAME@#$(SONAME)#" $(DESTDIR)$(libdir)/pkgconfig/re2.pc

.PHONY: testinstall
testinstall: static-testinstall shared-testinstall
	@echo
	@echo Install tests passed.
	@echo

.PHONY: static-testinstall
static-testinstall:
ifeq ($(shell uname),Darwin)
	@echo Skipping test for libre2.a on Darwin.
else ifeq ($(shell uname),SunOS)
	@echo Skipping test for libre2.a on SunOS.
else
	@mkdir -p obj
	@cp testinstall.cc obj/static-testinstall.cc
	(cd obj && export PKG_CONFIG_PATH=$(DESTDIR)$(libdir)/pkgconfig; \
	  $(CXX) static-testinstall.cc -o static-testinstall $(CXXFLAGS) $(LDFLAGS) \
	  $$($(PKG_CONFIG) re2 --cflags) \
	  $$($(PKG_CONFIG) re2 --libs | sed -e 's/-Wl / /g' | sed -e 's/-lre2/-l:libre2.a/'))
	obj/static-testinstall
endif

.PHONY: shared-testinstall
shared-testinstall:
	@mkdir -p obj
	@cp testinstall.cc obj/shared-testinstall.cc
	(cd obj && export PKG_CONFIG_PATH=$(DESTDIR)$(libdir)/pkgconfig; \
	  $(CXX) shared-testinstall.cc -o shared-testinstall $(CXXFLAGS) $(LDFLAGS) \
	  $$($(PKG_CONFIG) re2 --cflags) \
	  $$($(PKG_CONFIG) re2 --libs | sed -e 's/-Wl / /g'))
ifeq ($(shell uname),Darwin)
	DYLD_LIBRARY_PATH="$(DESTDIR)$(libdir):$(DYLD_LIBRARY_PATH)" obj/shared-testinstall
else
	LD_LIBRARY_PATH="$(DESTDIR)$(libdir):$(LD_LIBRARY_PATH)" obj/shared-testinstall
endif

.PHONY: benchlog
benchlog: obj/test/regexp_benchmark
	(echo '==BENCHMARK==' `hostname` `date`; \
	  (uname -a; $(CXX) --version; git rev-parse --short HEAD; file obj/test/regexp_benchmark) | sed 's/^/# /'; \
	  echo; \
	  ./obj/test/regexp_benchmark 'PCRE|RE2') | tee -a benchlog.$$(hostname | sed 's/\..*//')

.PHONY: log
log:
	$(MAKE) clean
	$(MAKE) CXXFLAGS="$(CXXFLAGS) -DLOGGING=1" \
		$(filter obj/test/exhaustive%_test,$(BIGTESTS))
	echo '#' RE2 exhaustive tests built by make log >re2-exhaustive.txt
	echo '#' $$(date) >>re2-exhaustive.txt
	obj/test/exhaustive_test |grep -v '^PASS$$' >>re2-exhaustive.txt
	obj/test/exhaustive1_test |grep -v '^PASS$$' >>re2-exhaustive.txt
	obj/test/exhaustive2_test |grep -v '^PASS$$' >>re2-exhaustive.txt
	obj/test/exhaustive3_test |grep -v '^PASS$$' >>re2-exhaustive.txt

	$(MAKE) CXXFLAGS="$(CXXFLAGS) -DLOGGING=1" obj/test/search_test
	echo '#' RE2 basic search tests built by make $@ >re2-search.txt
	echo '#' $$(date) >>re2-search.txt
	obj/test/search_test |grep -v '^PASS$$' >>re2-search.txt


================================================
FILE: README.md
================================================
# RE2, a regular expression library

RE2 is an efficient, principled regular expression library
that has been used in production at Google and many other places
since 2006.

_**Safety is RE2's primary goal.**_

RE2 was designed and implemented with an explicit goal of being able
to handle regular expressions from untrusted users without risk.
One of its primary guarantees is that the match time is linear in the
length of the input string. It was also written with production concerns in mind:
the parser, the compiler and the execution engines limit their memory usage
by working within a configurable budget—failing gracefully when exhausted—and
they avoid stack overflow by eschewing recursion.

It is not a goal to be faster than all other engines under all circumstances.
Although RE2 guarantees a running time that is asymptotically linear in
the length of the input, more complex expressions may incur larger constant factors;
longer expressions increase the overhead required to handle those expressions safely.
In a sense, RE2 is pessimistic where a backtracking engine is optimistic:
A backtracking engine tests each alternative sequentially, making it fast when the first alternative is common.
By contrast RE2 evaluates all alternatives in parallel, avoiding the performance penalty for the last alternative,
at the cost of some overhead. This pessimism is what makes RE2 secure.

It is also not a goal to implement all of the features offered by Perl, PCRE and other engines.
As a matter of principle, RE2 does not support constructs for which only backtracking solutions are known to exist.
Thus, backreferences and look-around assertions are not supported.

For more information, please refer to Russ Cox's articles on regular expression theory and practice:

* [Regular Expression Matching Can Be Simple And Fast](https://swtch.com/~rsc/regexp/regexp1.html)
* [Regular Expression Matching: the Virtual Machine Approach](https://swtch.com/~rsc/regexp/regexp2.html)
* [Regular Expression Matching in the Wild](https://swtch.com/~rsc/regexp/regexp3.html)

### Syntax

In POSIX mode, RE2 accepts standard POSIX (egrep) syntax regular expressions.
In Perl mode, RE2 accepts most Perl operators.  The only excluded ones are
those that require backtracking (and its potential for exponential runtime)
to implement.  These include backreferences (submatching is still okay)
and generalized assertions.
The [Syntax wiki page](https://github.com/google/re2/wiki/Syntax)
documents the supported Perl-mode syntax in detail.
The default is Perl mode.

### C++ API

RE2's native language is C++, although there are [ports and wrappers](#ports-and-wrappers) listed below.

#### Matching Interface

There are two basic operators:
`RE2::FullMatch` requires the regexp to match the entire input text, and
`RE2::PartialMatch` looks for a match for a substring of the input text,
returning the leftmost-longest match in POSIX mode and the
same match that Perl would have chosen in Perl mode.

Examples:

```cpp
assert(RE2::FullMatch("hello", "h.*o"))
assert(!RE2::FullMatch("hello", "e"))

assert(RE2::PartialMatch("hello", "h.*o"))
assert(RE2::PartialMatch("hello", "e"))
```

#### Submatch Extraction

Both matching functions take additional arguments in which submatches will be stored.
The argument can be a `string*`, or an integer type, or the type `absl::string_view*`.
(The `absl::string_view` type is very similar to the `std::string_view` type,
but for historical reasons, RE2 uses the former.)
A `string_view` is a pointer to the original input text, along with a count.
It behaves like a string but doesn't carry its own storage.
Like when using a pointer, when using a `string_view`
you must be careful not to use it once the original text has been deleted or gone out of scope.

Examples:

```cpp
// Successful parsing.
int i;
string s;
assert(RE2::FullMatch("ruby:1234", "(\\w+):(\\d+)", &s, &i));
assert(s == "ruby");
assert(i == 1234);

// Fails: "ruby" cannot be parsed as an integer.
assert(!RE2::FullMatch("ruby", "(.+)", &i));

// Success; does not extract the number.
assert(RE2::FullMatch("ruby:1234", "(\\w+):(\\d+)", &s));

// Success; skips NULL argument.
assert(RE2::FullMatch("ruby:1234", "(\\w+):(\\d+)", (void*)NULL, &i));

// Fails: integer overflow keeps value from being stored in i.
assert(!RE2::FullMatch("ruby:123456789123", "(\\w+):(\\d+)", &s, &i));
```

#### Pre-Compiled Regular Expressions

The examples above all recompile the regular expression on each call.
Instead, you can compile it once to an RE2 object and reuse that object for each call.

Example:
```cpp
RE2 re("(\\w+):(\\d+)");
assert(re.ok());  // compiled; if not, see re.error();

assert(RE2::FullMatch("ruby:1234", re, &s, &i));
assert(RE2::FullMatch("ruby:1234", re, &s));
assert(RE2::FullMatch("ruby:1234", re, (void*)NULL, &i));
assert(!RE2::FullMatch("ruby:123456789123", re, &s, &i));
```

#### Options

The constructor takes an optional second argument that can
be used to change RE2's default options.
For example, `RE2::Quiet` silences the error messages that are
usually printed when a regular expression fails to parse:

```cpp
RE2 re("(ab", RE2::Quiet);  // don't write to stderr for parser failure
assert(!re.ok());  // can check re.error() for details
```

Other useful predefined options are `Latin1` (disable UTF-8) and `POSIX`
(use POSIX syntax and leftmost longest matching).

You can also declare your own `RE2::Options` object and then configure it as you like.
See the [header](https://github.com/google/re2/blob/main/re2/re2.h) for the full set of options.

#### Unicode Normalization

RE2 operates on Unicode code points: it makes no attempt at normalization.
For example, the regular expression /ü/ (U+00FC, u with diaeresis)
does not match the input "ü" (U+0075 U+0308, u followed by combining diaeresis).
Normalization is a long, involved topic.
The simplest solution, if you need such matches, is to normalize both the regular expressions
and the input in a preprocessing step before using RE2.
For more details on the general topic, see <https://www.unicode.org/reports/tr15/>.

#### Additional Tips and Tricks

For advanced usage, like constructing your own argument lists,
or using RE2 as a lexer, or parsing hex, octal, and C-radix numbers,
see [re2.h](https://github.com/google/re2/blob/main/re2/re2.h).

### Installation

RE2 can be built and installed using GNU make, CMake, or Bazel.
The simplest installation instructions are:

	make
	make test
	make benchmark
	make install
	make testinstall

Building RE2 requires a C++17 compiler and the [Abseil](https://github.com/abseil/abseil-cpp) library.
Building the tests and benchmarks requires
[GoogleTest](https://github.com/google/googletest)
and [Benchmark](https://github.com/google/benchmark).
To obtain those:

- Linux: `apt install libabsl-dev libgtest-dev libbenchmark-dev`
- macOS: `brew install abseil googletest google-benchmark pkg-config-wrapper`
- Windows: `vcpkg install abseil gtest benchmark` \
  or `vcpkg add port abseil gtest benchmark`

Once those are installed, the build has to be able to find them.
If the standard Makefile has trouble, then switching to CMake can help:

	rm -rf build
	cmake -DRE2_TEST=ON -DRE2_BENCHMARK=ON -S . -B build
	cd build
	make
	make test
	make install

When using CMake, with benchmarks enabled, `make test` builds and runs test binaries
and builds a `regexp_benchmark` binary but does not run it.
If you don't need the tests or benchmarks at all, you can omit the corresponding `-D` arguments,
and then you don't need the GoogleTest or Benchmark dependencies either.

Another useful option is `-DRE2_USE_ICU=ON`, which adds a dependency on the
ICU Unicode library but also extends the list of property names available in the `\p` and `\P` patterns.

CMake can also be used to generate Visual Studio and Xcode projects, as well as
Cygwin, MinGW, and MSYS makefiles.

 - Visual Studio users: You need Visual Studio 2019 or later.
 - Cygwin users: You must run CMake from the Cygwin command line, not the Windows command line.

If you are adding RE2 to your own CMake project,
CMake has two ways to use a dependency: `add_subdirectory()`,
which is when the dependency's **_sources_** are in a subdirectory of your project;
and `find_package()`, which is when the dependency's
**_binaries_** have been built and installed somewhere on your system.
The Abseil documentation walks through the former [here](https://abseil.io/docs/cpp/quickstart-cmake)
versus the latter [here](https://abseil.io/docs/cpp/tools/cmake-installs).
Once you get Abseil working, getting RE2 working will be a very similar process and,
either way, `target_link_libraries(… re2::re2)` should Just Work™.

If you are using [Bazel](https://bazel.io), it will handle the dependencies for you,
although you still need to download Bazel,
which you can do with [Bazelisk](https://github.com/bazelbuild/bazelisk).

	go install github.com/bazelbuild/bazelisk@latest
	# or on mac: brew install bazelisk

	bazelisk build :all
	bazelisk test :all

If you are using RE2 from another project, you need to make sure you are
using at least C++17.
See the RE2 [.bazelrc](https://github.com/google/re2/blob/main/.bazelrc) file for an example.

### Ports and Wrappers

RE2 is implemented in C++.

The official Python wrapper is [in the `python` directory](https://github.com/google/re2/tree/main/python)
and [published on PyPI as `google-re2`](https://pypi.org/project/google-re2/).
Note that there is also a PyPI `re2` but it is not by the RE2 authors and is unmaintained. Use `google-re2`.

There are also other unofficial wrappers:

- A C wrapper is at <https://github.com/marcomaggi/cre2/>.
- A D wrapper is at <https://github.com/ShigekiKarita/re2d/> and [on DUB](https://code.dlang.org/packages/re2d).
- An Erlang wrapper is at <https://github.com/dukesoferl/re2/> and [on Hex](https://hex.pm/packages/re2).
- An Inferno wrapper is at <https://github.com/powerman/inferno-re2/>.
- A Node.js wrapper is at <https://github.com/uhop/node-re2/> and [on NPM](https://www.npmjs.com/package/re2).
- An OCaml wrapper is at <https://github.com/janestreet/re2/> and [on OPAM](https://opam.ocaml.org/packages/re2/).
- A Perl wrapper is at <https://github.com/dgl/re-engine-RE2/> and [on CPAN](https://metacpan.org/pod/re::engine::RE2).
- An R wrapper is at <https://github.com/girishji/re2/> and [on CRAN](https://cran.r-project.org/web/packages/re2/index.html).
- A Ruby wrapper is at <https://github.com/mudge/re2/> and on RubyGems (rubygems.org).
- A WebAssembly wrapper is at <https://github.com/google/re2-wasm/> and on NPM (npmjs.com).

[RE2J](https://github.com/google/re2j) is a port of the RE2 C++ code to pure Java,
and [RE2JS](https://github.com/le0pard/re2js) is a port of RE2J to JavaScript.

The [Go `regexp` package](https://go.dev/pkg/regexp)
and [Rust `regex` crate](https://docs.rs/regex)
do not share code with RE2, but they follow the same principles,
accept the same syntax, and provide the same efficiency guarantees.

### Contact

The [issue tracker](https://github.com/google/re2/issues) is the best place for discussions.

There is a [mailing list](https://groups.google.com/group/re2-dev) for keeping up with code changes.

Please read the [contribution guide](https://github.com/google/re2/wiki/Contribute) before sending changes.
In particular, note that RE2 does not use GitHub pull requests.


================================================
FILE: SECURITY.md
================================================
To report a security issue, please use https://g.co/vulnz. We use
https://g.co/vulnz for our intake, and do coordination and disclosure here on
GitHub (including using GitHub Security Advisory). The Google Security Team will
respond within 5 working days of your report on https://g.co/vulnz.


================================================
FILE: WORKSPACE.bazel
================================================
# Copyright 2009 The RE2 Authors.  All Rights Reserved.
# Use of this source code is governed by a BSD-style
# license that can be found in the LICENSE file.

# Bazel (http://bazel.build/) WORKSPACE file for RE2.

workspace(name = "com_googlesource_code_re2")


================================================
FILE: WORKSPACE.bzlmod
================================================
# Copyright 2009 The RE2 Authors.  All Rights Reserved.
# Use of this source code is governed by a BSD-style
# license that can be found in the LICENSE file.

# Bazel (http://bazel.build/) WORKSPACE file for RE2.

workspace(name = "com_googlesource_code_re2")


================================================
FILE: app/BUILD.bazel
================================================
# Copyright 2009 The RE2 Authors.  All Rights Reserved.
# Use of this source code is governed by a BSD-style
# license that can be found in the LICENSE file.

# Bazel (http://bazel.build/) BUILD file for RE2 app.

cc_binary(
    name = "_re2.js",
    testonly = 1,
    srcs = ["_re2.cc"],
    linkopts = [
        "--bind",
        "-sENVIRONMENT=web",
        "-sSINGLE_FILE=1",
        "-sMODULARIZE=1",
        "-sEXPORT_ES6=1",
        "-sEXPORT_NAME=loadModule",
        "-sUSE_PTHREADS=0",
    ],
    deps = [
        "//:re2",
        "//:testing",
    ],
)


================================================
FILE: app/_re2.cc
================================================
// Copyright 2022 The RE2 Authors.  All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

#include <memory>
#include <string>

#include <emscripten/bind.h>
#include "re2/prog.h"
#include "re2/re2.h"
#include "re2/regexp.h"

namespace re2_app {

struct Info {
  std::string pattern;
  std::string error;
  std::string prefix;
  bool prefix_foldcase = false;
  std::string accel_prefix;
  bool accel_prefix_foldcase = false;
  int num_captures;
  bool is_one_pass;
  bool can_bit_state;
  std::string bytecode;
  std::string bytemap;
};

Info GetInfo(const std::string& pattern) {
  Info info;
  info.pattern = pattern;

  RE2::Options options;
  re2::RegexpStatus status;
  re2::Regexp* regexp = re2::Regexp::Parse(
      pattern, static_cast<re2::Regexp::ParseFlags>(options.ParseFlags()),
      &status);
  if (regexp == nullptr) {
    info.error = "failed to parse pattern: " + status.Text();
    return info;
  }

  std::string prefix;
  bool prefix_foldcase;
  re2::Regexp* suffix;
  if (regexp->RequiredPrefix(&prefix, &prefix_foldcase, &suffix)) {
    info.prefix = prefix;
    info.prefix_foldcase = prefix_foldcase;
  } else {
    suffix = regexp->Incref();
  }

  std::unique_ptr<re2::Prog> prog(suffix->CompileToProg(options.max_mem()));
  if (prog == nullptr) {
    info.error = "failed to compile forward Prog";
    suffix->Decref();
    regexp->Decref();
    return info;
  }

  if (regexp->RequiredPrefixForAccel(&prefix, &prefix_foldcase)) {
    info.accel_prefix = prefix;
    info.accel_prefix_foldcase = prefix_foldcase;
  }

  info.num_captures = suffix->NumCaptures();
  info.is_one_pass = prog->IsOnePass();
  info.can_bit_state = prog->CanBitState();
  info.bytecode = prog->Dump();
  info.bytemap = prog->DumpByteMap();

  suffix->Decref();
  regexp->Decref();
  return info;
}

EMSCRIPTEN_BINDINGS(_re2) {
  emscripten::value_object<Info>("Info")
      .field("pattern", &Info::pattern)
      .field("error", &Info::error)
      .field("prefix", &Info::prefix)
      .field("prefix_foldcase", &Info::prefix_foldcase)
      .field("accel_prefix", &Info::accel_prefix)
      .field("accel_prefix_foldcase", &Info::accel_prefix_foldcase)
      .field("num_captures", &Info::num_captures)
      .field("is_one_pass", &Info::is_one_pass)
      .field("can_bit_state", &Info::can_bit_state)
      .field("bytecode", &Info::bytecode)
      .field("bytemap", &Info::bytemap);

  emscripten::function("getInfo", &GetInfo);
}

}  // namespace re2_app


================================================
FILE: app/_re2.d.ts
================================================
// Copyright 2022 The RE2 Authors.  All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

export type Info = {
  pattern: ArrayBuffer|Uint8Array|Uint8ClampedArray|Int8Array|string,
  error: ArrayBuffer|Uint8Array|Uint8ClampedArray|Int8Array|string,
  prefix: ArrayBuffer|Uint8Array|Uint8ClampedArray|Int8Array|string,
  prefix_foldcase: boolean,
  accel_prefix: ArrayBuffer|Uint8Array|Uint8ClampedArray|Int8Array|string,
  accel_prefix_foldcase: boolean,
  num_captures: number,
  is_one_pass: boolean,
  can_bit_state: boolean,
  bytecode: ArrayBuffer|Uint8Array|Uint8ClampedArray|Int8Array|string,
  bytemap: ArrayBuffer|Uint8Array|Uint8ClampedArray|Int8Array|string,
};

export interface MainModule {
  getInfo(pattern: ArrayBuffer|Uint8Array|Uint8ClampedArray|Int8Array|string): Info;
}

export default function loadModule(): Promise<MainModule>;


================================================
FILE: app/app.ts
================================================
// Copyright 2022 The RE2 Authors.  All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

import {css, html, LitElement, render} from 'lit';
import {customElement} from 'lit/decorators.js';

import /*default*/ loadModule from './_re2';
import {Info, MainModule} from './_re2';

var _re2: MainModule;
loadModule().then((module: MainModule) => {
  _re2 = module;
  render(html`<title>re2-dev</title><re2-dev></re2-dev>`, document.body);
});

@customElement('re2-dev')
export class RE2Dev extends LitElement {
  private _pattern: string = '';
  private _info: Info|null = null;

  constructor() {
    super();
    this._pattern = decodeURIComponent(window.location.hash.slice(1));
    this._info = this._pattern ? _re2.getInfo(this._pattern) : null;
    this.requestUpdate();
  }

  private _onChange = (e: Event) => {
    this._pattern = (e.target as HTMLInputElement).value;
    this._info = this._pattern ? _re2.getInfo(this._pattern) : null;
    this.requestUpdate();
    window.location.hash = '#' + encodeURIComponent(this._pattern);
  };

  static override styles = css`
.code {
  font-family: monospace;
  white-space: pre-line;
}
`;

  override render() {
    var fragments = [];
    fragments.push(html`
<div>
  <input type="text" size="48" @change=${this._onChange} .value=${this._pattern}>
</div>
`);

    if (this._info === null) {
      return html`${fragments}`;
    }

    if (this._info.error) {
      fragments.push(html`
<br>
<div>
  error:
  <span class="code">${this._info.error}</span>
</div>
`);
      return html`${fragments}`;
    }

    fragments.push(html`
<br>
<div>
  pattern:
  <span class="code">${this._info.pattern}</span>
  <br>
  prefix:
  <span class="code">${this._info.prefix}</span>
  ·
  _foldcase:
  <span class="code">${this._info.prefix_foldcase}</span>
  <br>
  accel_prefix:
  <span class="code">${this._info.accel_prefix}</span>
  ·
  _foldcase:
  <span class="code">${this._info.accel_prefix_foldcase}</span>
  <br>
  num_captures:
  <span class="code">${this._info.num_captures}</span>
  <br>
  is_one_pass:
  <span class="code">${this._info.is_one_pass}</span>
  <br>
  can_bit_state:
  <span class="code">${this._info.can_bit_state}</span>
  <br>
  <br>
  bytecode:
  <br>
  <span class="code">${this._info.bytecode}</span>
  <br>
  bytemap:
  <br>
  <span class="code">${this._info.bytemap}</span>
</div>
`);
    return html`${fragments}`;
  }
}

declare global {
  interface HTMLElementTagNameMap {
    're2-dev': RE2Dev;
  }
}


================================================
FILE: app/build.sh
================================================
#!/bin/bash
set -eux

SRCDIR=$(readlink --canonicalize $(dirname $0))
DSTDIR=$(mktemp --directory --tmpdir $(basename $0).XXXXXXXXXX)

cd ${SRCDIR}
# Emscripten doesn't support `-fstack-protector`.
AR=emar CC=emcc \
  bazel build \
  --copt=-fno-stack-protector \
  --compilation_mode=opt -- :all
cp ../bazel-bin/app/_re2.js ${DSTDIR}
bazel clean --expunge
cp app.ts index.html _re2.d.ts ${DSTDIR}
cp package.json rollup.config.js tsconfig.json ${DSTDIR}

cd ${DSTDIR}
npm install
npx tsc
npx rollup -c rollup.config.js -d deploy

cd ${SRCDIR}
mkdir deploy
cat >deploy/index.html <<EOF
<html><head><meta http-equiv="refresh" content="0; url=https://github.com/google/re2"></head><body></body></html>
EOF
mkdir deploy/app
cp ${DSTDIR}/deploy/* deploy/app
ls -lR deploy

exit 0


================================================
FILE: app/index.html
================================================
<!DOCTYPE html>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>:root { color-scheme: dark light; }</style>
<script type="module" src="app.js"></script>


================================================
FILE: app/package.json
================================================
{
  "dependencies": {
    "lit": "*"
  },
  "devDependencies": {
    "@rollup/plugin-node-resolve": "*",
    "@rollup/plugin-terser": "*",
    "@web/rollup-plugin-html": "*",
    "@web/rollup-plugin-import-meta-assets": "*",
    "rollup": "~2",
    "tslib": "*",
    "typescript": "*"
  }
}


================================================
FILE: app/rollup.config.js
================================================
// Copyright 2022 The RE2 Authors.  All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

import nodeResolve from '@rollup/plugin-node-resolve';
import terser from '@rollup/plugin-terser';
import html from '@web/rollup-plugin-html';
import {importMetaAssets} from '@web/rollup-plugin-import-meta-assets';

export default {
  input: 'index.html',
  output: {
    entryFileNames: '[hash].js',
    chunkFileNames: '[hash].js',
    assetFileNames: '[hash][extname]',
    format: 'es',
  },
  preserveEntrySignatures: false,
  plugins:
      [
        html({
          minify: true,
        }),
        nodeResolve(),
        terser(),
        importMetaAssets(),
      ],
};


================================================
FILE: app/tsconfig.json
================================================
{
  "compilerOptions": {
    "target": "esnext",
    "module": "esnext",
    "moduleResolution": "node",
    "noEmitOnError": true,
    "lib": ["esnext", "dom"],
    "strict": true,
    "esModuleInterop": false,
    "allowSyntheticDefaultImports": true,
    "experimentalDecorators": true,
    "importHelpers": true,
    "sourceMap": true,
    "inlineSources": true,
    "incremental": true
  }
}


================================================
FILE: benchlog/benchplot.py
================================================
#!/usr/bin/env python

import argparse     # for ArgumentParser
import subprocess   # for Popen
import tempfile     # for NamedTemporaryFile
import os           # for remove

class gnuplot(object):

    output = "result.png"

    script = """
             set terminal png size 1024, 768
             set output "{}.png"
             set title "re2 benchlog"
             set datafile separator ";"
             set grid x y
             set ylabel "MB/s"
             set autoscale
             plot """

    template = """'{}' using 1:5:xticlabels(2) with linespoints linewidth 3 title "{}",\\\n"""

    benchdata = dict()
    tempfiles = []

    def __enter__(self):
        return self

    def __exit__(self, type, value, traceback):
        """
        remove all temporary files
        """

        for filename in self.tempfiles:
            os.remove(filename)

    def parse_re2_benchlog(self, filename):
        """
        parse the input benchlog and return a dictionary contain bench data
        """

        benchdata = self.benchdata

        with open(filename) as f:

            for raw in f.readlines():

                data = raw.split('\t')

                if len(data) == 4:

                    data = data[0].split('/') + data[1:]
                    data = list(map(str.strip, data))

                    if not benchdata.get(data[0]):
                        benchdata[data[0]] = [ data[1:] ]
                    else:
                        benchdata[data[0]].append(data[1:])

    def gen_csv(self):
        """
        generate temporary csv files
        """

        for name, data in self.benchdata.items():

            with tempfile.NamedTemporaryFile(delete=False) as f:

                for index, line in enumerate(data):
                    f.write('{};{}\n'.format(index, ';'.join(line)).encode())

                self.tempfiles.append(f.name)
                self.script = self.script + self.template.format(f.name, name)

    def run(self):
        self.gen_csv()
        script = self.script[:-3].format(self.output)
        command = subprocess.Popen(['gnuplot'], stdin=subprocess.PIPE)
        command.communicate(script.encode())


if __name__ == '__main__':

    parser = argparse.ArgumentParser(description='generate plots for benchlog')
    parser.add_argument('benchlog', type=str, help='benchlog generated by re2')
    args = parser.parse_args()

    try:
        subprocess.Popen(['gnuplot'], stdin=subprocess.PIPE)
    except FileNotFoundError:
        print('you can install "gnuplot" to generate plots automatically')
        exit(1)

    with gnuplot() as plot:
        plot.output = args.benchlog
        plot.parse_re2_benchlog(args.benchlog)
        plot.run()


================================================
FILE: benchlog/mktable
================================================
#!/usr/bin/perl
# XXX

sub table() {
	my ($name) = @_;
	print <<'EOF';
<table border=0>
<tr><th>System</th><th>PCRE</th><th>RE2</th></tr>
EOF
	foreach my $sys (@sys) {
		my $ns_pcre = $data{$sys}->{sprintf($name, "PCRE")}->{'ns/op'};
		my $ns_re2 = $data{$sys}->{sprintf($name, "RE2")}->{'ns/op'};
		printf "<tr><td>%s</td><td>%.1f µs</td><td>%.1f µs</td></tr>\n", $sysname{$sys}, $ns_pcre/1000., $ns_re2/1000.;
	}
	print <<'EOF';
<tr height=5><td colspan=3></td></tr>
</table>
EOF
}

@sizes = (
	"8", "16", "32", "64", "128", "256", "512",
	"1K", "2K", "4K", "8K", "16K", "32K", "64K", "128K", "256K", "512K",
	"1M", "2M", "4M", "8M", "16M"
);

%color = (
	"PCRE" => "0.7 0 0",
	"RE2" => "0 0 1",
);

$ngraph = 0;

sub graph() {
	my ($name) = @_;
	
	my $sys = "wreck";
	my $base = sprintf("regexp3g%d", ++$ngraph);

	open(JGR, ">$base.jgr") || die "open >$base.jgr: $!";
	printf JGR "bbox -20 -12 392 95\n";
	printf JGR "newgraph clip x_translate 0.25 y_translate 0.25\n";
	$ymax = 0;
	%lastx = ();
	%lasty = ();
	foreach my $who ("PCRE", "RE2") {
		printf JGR "newcurve pts\n";
		for(my $i=0; $i<@sizes; $i++) {
			my $key = sprintf("%s%s/%s", $name, $who, $sizes[$i]);
			my $val = $data{$sys}->{$key}->{'MB/s'};
			next if !defined($val);
			if($val > $ymax) {
				$ymax = $val;
			}
			$lastx{$who} = $i;
			$lasty{$who} = $val;
			printf JGR "$i %f (* %s *)\n", $val, $key;
		}
		my $color = $color{$who};
		printf JGR "marktype none color $color linethickness 2 linetype solid label : $who\n";
	}
	my $n = @sizes;
	printf JGR "xaxis min -1 max $n size 5 label : text size (bytes)\n";
	printf JGR "  no_auto_hash_marks hash_labels fontsize 9\n";
	for($i=0; $i<@sizes; $i+=3) {
		printf JGR "  hash_at $i hash_label at $i : $sizes[$i]\n";
	}
	my $y = 1;
	while(10*$y <= $ymax) {
		$y = 10*$y;
	}
	for($i=2; $i<=10; $i++) {
		if($i*$y > $ymax) {
			$y = $i*$y;
			last;
		}
	}
	foreach my $who ("PCRE", "RE2") {
		$x1 = $lastx{$who};
		$y1 = $lasty{$who};
		$x1 *= 1.01;
		my $v = "vjc";
		if($y1 < 0.05 * $y) {
			$v = "vjb";
			$y1 = 0.05 * $y;
		}
		printf JGR "newstring x $x1 y $y1 hjl $v : $who\n";
	}
	printf JGR "yaxis min 0 max $y size 1 label : speed (MB/s)\n";
	printf JGR "  hash_labels fontsize 9\n";
	# printf JGR "legend defaults font Times-Roman fontsize 10 x 0 y $y hjl vjt\n";

	system("jgraph $base.jgr >$base.eps"); # die "system: $!";
	system("gs -dTextAlphaBits=4 -dGraphicsAlphaBits=4 -dEPSCrop -sDEVICE=png16m -r100 -sOutputFile=$base.png -dBATCH -dQUIT -dQUIET -dNOPAUSE $base.eps");
	
	printf "<img src=$base.png>\n"
	
}

sub skip() {
	while(<>) {
		if(/^<!-- -->/) {
			print;
			last;
		}
	}
}

@sys = ("r70", "c2", "wreck", "mini");
%sysname = (
	"r70" => "AMD Opteron 8214 HE, 2.2 GHz",
	"c2" => "Intel Core2 Duo E7200, 2.53 GHz",
	"wreck" => "Intel Xeon 5150, 2.66 GHz (Mac Pro)",
	"mini" => "Intel Core2 T5600, 1.83 GHz (Mac Mini)",
);

%func = (
	"table" => \&table,
	"graph" => \&graph,
	
);

foreach my $sys (@sys) {
	open(F, "benchlog.$sys") || die "open benchlog.$sys: $!";
	my %sysdat;
	while(<F>) {
		if(/^([A-Za-z0-9_\/]+)\s+(\d+)\s+(\d+) ns\/op/) {
			my %row;
			$row{"name"} = $1;
			$row{"iter"} = $2;
			$row{"ns/op"} = $3;
			if(/([\d.]+) MB\/s/){
				$row{"MB/s"} = $1;
			}
			$sysdat{$row{"name"}} = \%row;
		}
	}
	close F;	
	$data{$sys} = \%sysdat;
}

while(<>) {
	print;
	if(/^<!-- benchlog (\w+) -->/) {
		$func{$1}();
		skip();
		next;
	}
	if(/^<!-- benchlog (\w+) ([%\w]+) -->/) {
		$func{$1}($2);
		skip();
		next;
	}
}



================================================
FILE: doc/mksyntaxgo
================================================
#!/bin/sh

set -e
out=$GOROOT/src/regexp/syntax/doc.go
cp syntax.txt $out
sam -d $out <<'!'
,x g/NOT SUPPORTED/d
/^Unicode character class/,$d
,s/[«»]//g
,x g/^Possessive repetitions:/d
,x g/\\C/d
,x g/Flag syntax/d
,s/.=(true|false)/flag &/g
,s/^Flags:/  Flag syntax is xyz (set) or -xyz (clear) or xy-z (set xy, clear z). The flags are:\n/
,s/\n\n\n+/\n\n/g
,x/(^.*	.*\n)+/ | awk -F'	' '{printf("  %-14s %s\n", $1, $2)}'
1,2c
// Copyright 2012 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Code generated by mksyntaxgo from the RE2 distribution. DO NOT EDIT.

/*
Package syntax parses regular expressions into parse trees and compiles
parse trees into programs. Most clients of regular expressions will use the
facilities of package [regexp] (such as [regexp.Compile] and [regexp.Match]) instead of this package.

# Syntax

The regular expression syntax understood by this package when parsing with the [Perl] flag is as follows.
Parts of the syntax can be disabled by passing alternate flags to [Parse].

.
$a
Unicode character classes are those in [unicode.Categories] and [unicode.Scripts].
*/
package syntax
.
w
q
!


================================================
FILE: doc/mksyntaxhtml
================================================
#!/bin/sh

cp syntax.txt syntax.html
sam -d syntax.html <<'!'
,s/\&/\&amp;/g
,s/</\&lt;/g
,s/>/\&gt;/g
,s!== (([^()]|\([^()]*\))*)!≡ <code>\1</code>!g
,s!«!<code>!g
,s!»!</code>!g
,s! vim$! <font size=-2>VIM</font>!g
,s! pcre$! <font size=-2>PCRE</font>!g
,s! perl$! <font size=-2>PERL</font>!g
,x g/NOT SUPPORTED/ s!^[^	]+!<font color=#808080>&</font>!
,s!NOT SUPPORTED!!g
,s!(^[^	]+)	(.*)\n!<tr><td><code>\1</code></td><td>\2</td></tr>\n!g
,s!.*:$!<b>&</b>!g
,s!^$!<tr><td></td></tr>!g
,x v/<tr>/ s!.*!<tr><td colspan=2>&</td></tr>!
1,2c
<html>
<!-- AUTOMATICALLY GENERATED by mksyntaxhtml -->
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<title>RE2 regular expression syntax reference</title>
</head>
<body>
<h1>RE2 regular expression syntax reference</h1>

<table border=0 cellpadding=2 cellspacing=2>
<tr><td colspan=2>This page lists the regular expression syntax accepted by RE2.</td></tr>
<tr><td colspan=2>It also lists syntax accepted by PCRE, PERL, and VIM.</td></tr>
<tr><td colspan=2>Grayed out expressions are not supported by RE2.</td></tr>
.
$a
</table>
</body>
</html>
.
w
q
!


================================================
FILE: doc/mksyntaxwiki
================================================
#!/bin/sh

cp syntax.txt syntax.wiki
sam -d syntax.wiki <<'!'
,s!`!`````!g
,s!== (([^()]|\([^()]*\))*)!≡ `\1`!g
,s!«!`!g
,s!»!`!g
,s! vim$! <font size="1">VIM</font>!g
,s! pcre$! <font size="1">PCRE</font>!g
,s! perl$! <font size="1">PERL</font>!g
,s!(^[^	]+)	(.*)\n!`\1`	\2\n!g
,x g/NOT SUPPORTED/ s!^[^	]+!<font color="#808080">&</font>!
,s!NOT SUPPORTED!<font size="1">(&)</font>!g
,s!(^[^	]+)	(.*)\n!<tr><td>\1</td><td>\2</td></tr>\n!g
,s!.*:$!<b>&</b>!g
,s!^$!<tr><td></td></tr>!g
,x v/<tr>/ s!.*!<tr><td colspan="2">&</td></tr>!
1,2c
#summary I define UNIX as “30 definitions of regular expressions living under one roof.” —Don Knuth

<wiki:comment>
GENERATED BY mksyntaxwiki.  DO NOT EDIT
</wiki:comment>

<table border="0" cellpadding="2" cellspacing="2">
<tr><td colspan="2">This page lists the regular expression syntax accepted by RE2.</td></tr>
<tr><td colspan="2">It also lists syntax accepted by PCRE, PERL, and VIM.</td></tr>
<tr><td colspan="2">Grayed out expressions are not supported by RE2.</td></tr>
.
$a
</table>
.
w
q
!


================================================
FILE: doc/syntax.html
================================================
<html>
<!-- AUTOMATICALLY GENERATED by mksyntaxhtml -->
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<title>RE2 regular expression syntax reference</title>
</head>
<body>
<h1>RE2 regular expression syntax reference</h1>

<table border=0 cellpadding=2 cellspacing=2>
<tr><td colspan=2>This page lists the regular expression syntax accepted by RE2.</td></tr>
<tr><td colspan=2>It also lists syntax accepted by PCRE, PERL, and VIM.</td></tr>
<tr><td colspan=2>Grayed out expressions are not supported by RE2.</td></tr>
<tr><td></td></tr>
<tr><td colspan=2><b>Single characters:</b></td></tr>
<tr><td><code>.</code></td><td>any character, possibly including newline (s=true)</td></tr>
<tr><td><code>[xyz]</code></td><td>character class</td></tr>
<tr><td><code>[^xyz]</code></td><td>negated character class</td></tr>
<tr><td><code>\d</code></td><td>Perl character class</td></tr>
<tr><td><code>\D</code></td><td>negated Perl character class</td></tr>
<tr><td><code>[[:alpha:]]</code></td><td>ASCII character class</td></tr>
<tr><td><code>[[:^alpha:]]</code></td><td>negated ASCII character class</td></tr>
<tr><td><code>\pN</code></td><td>Unicode character class (one-letter name)</td></tr>
<tr><td><code>\p{Greek}</code></td><td>Unicode character class</td></tr>
<tr><td><code>\PN</code></td><td>negated Unicode character class (one-letter name)</td></tr>
<tr><td><code>\P{Greek}</code></td><td>negated Unicode character class</td></tr>
<tr><td></td></tr>
<tr><td colspan=2><b>Composites:</b></td></tr>
<tr><td><code>xy</code></td><td><code>x</code> followed by <code>y</code></td></tr>
<tr><td><code>x|y</code></td><td><code>x</code> or <code>y</code> (prefer <code>x</code>)</td></tr>
<tr><td></td></tr>
<tr><td colspan=2><b>Repetitions:</b></td></tr>
<tr><td><code>x*</code></td><td>zero or more <code>x</code>, prefer more</td></tr>
<tr><td><code>x+</code></td><td>one or more <code>x</code>, prefer more</td></tr>
<tr><td><code>x?</code></td><td>zero or one <code>x</code>, prefer one</td></tr>
<tr><td><code>x{n,m}</code></td><td><code>n</code> or <code>n</code>+1 or ... or <code>m</code> <code>x</code>, prefer more</td></tr>
<tr><td><code>x{n,}</code></td><td><code>n</code> or more <code>x</code>, prefer more</td></tr>
<tr><td><code>x{n}</code></td><td>exactly <code>n</code> <code>x</code></td></tr>
<tr><td><code>x*?</code></td><td>zero or more <code>x</code>, prefer fewer</td></tr>
<tr><td><code>x+?</code></td><td>one or more <code>x</code>, prefer fewer</td></tr>
<tr><td><code>x??</code></td><td>zero or one <code>x</code>, prefer zero</td></tr>
<tr><td><code>x{n,m}?</code></td><td><code>n</code> or <code>n</code>+1 or ... or <code>m</code> <code>x</code>, prefer fewer</td></tr>
<tr><td><code>x{n,}?</code></td><td><code>n</code> or more <code>x</code>, prefer fewer</td></tr>
<tr><td><code>x{n}?</code></td><td>exactly <code>n</code> <code>x</code></td></tr>
<tr><td><code><font color=#808080>x{}</font></code></td><td>(≡ <code>x*</code>)  <font size=-2>VIM</font></td></tr>
<tr><td><code><font color=#808080>x{-}</font></code></td><td>(≡ <code>x*?</code>)  <font size=-2>VIM</font></td></tr>
<tr><td><code><font color=#808080>x{-n}</font></code></td><td>(≡ <code>x{n}?</code>)  <font size=-2>VIM</font></td></tr>
<tr><td><code><font color=#808080>x=</font></code></td><td>(≡ <code>x?</code>)  <font size=-2>VIM</font></td></tr>
<tr><td></td></tr>
<tr><td colspan=2>Implementation restriction: The counting forms <code>x{n,m}</code>, <code>x{n,}</code>, and <code>x{n}</code></td></tr>
<tr><td colspan=2>reject forms that create a minimum or maximum repetition count above 1000.</td></tr>
<tr><td colspan=2>Unlimited repetitions are not subject to this restriction.</td></tr>
<tr><td></td></tr>
<tr><td colspan=2><b>Possessive repetitions:</b></td></tr>
<tr><td><code><font color=#808080>x*+</font></code></td><td>zero or more <code>x</code>, possessive </td></tr>
<tr><td><code><font color=#808080>x++</font></code></td><td>one or more <code>x</code>, possessive </td></tr>
<tr><td><code><font color=#808080>x?+</font></code></td><td>zero or one <code>x</code>, possessive </td></tr>
<tr><td><code><font color=#808080>x{n,m}+</font></code></td><td><code>n</code> or ... or <code>m</code> <code>x</code>, possessive </td></tr>
<tr><td><code><font color=#808080>x{n,}+</font></code></td><td><code>n</code> or more <code>x</code>, possessive </td></tr>
<tr><td><code><font color=#808080>x{n}+</font></code></td><td>exactly <code>n</code> <code>x</code>, possessive </td></tr>
<tr><td></td></tr>
<tr><td colspan=2><b>Grouping:</b></td></tr>
<tr><td><code>(re)</code></td><td>numbered capturing group (submatch)</td></tr>
<tr><td><code>(?P&lt;name&gt;re)</code></td><td>named &amp; numbered capturing group (submatch)</td></tr>
<tr><td><code>(?&lt;name&gt;re)</code></td><td>named &amp; numbered capturing group (submatch)</td></tr>
<tr><td><code><font color=#808080>(?'name're)</font></code></td><td>named &amp; numbered capturing group (submatch) </td></tr>
<tr><td><code>(?:re)</code></td><td>non-capturing group</td></tr>
<tr><td><code>(?flags)</code></td><td>set flags within current group; non-capturing</td></tr>
<tr><td><code>(?flags:re)</code></td><td>set flags during re; non-capturing</td></tr>
<tr><td><code><font color=#808080>(?#text)</font></code></td><td>comment </td></tr>
<tr><td><code><font color=#808080>(?|x|y|z)</font></code></td><td>branch numbering reset </td></tr>
<tr><td><code><font color=#808080>(?&gt;re)</font></code></td><td>possessive match of <code>re</code> </td></tr>
<tr><td><code><font color=#808080>re@&gt;</font></code></td><td>possessive match of <code>re</code>  <font size=-2>VIM</font></td></tr>
<tr><td><code><font color=#808080>%(re)</font></code></td><td>non-capturing group  <font size=-2>VIM</font></td></tr>
<tr><td></td></tr>
<tr><td colspan=2><b>Flags:</b></td></tr>
<tr><td><code>i</code></td><td>case-insensitive (default false)</td></tr>
<tr><td><code>m</code></td><td>multi-line mode: <code>^</code> and <code>$</code> match begin/end line in addition to begin/end text (default false)</td></tr>
<tr><td><code>s</code></td><td>let <code>.</code> match <code>\n</code> (default false)</td></tr>
<tr><td><code>U</code></td><td>ungreedy: swap meaning of <code>x*</code> and <code>x*?</code>, <code>x+</code> and <code>x+?</code>, etc (default false)</td></tr>
<tr><td colspan=2>Flag syntax is <code>xyz</code> (set) or <code>-xyz</code> (clear) or <code>xy-z</code> (set <code>xy</code>, clear <code>z</code>).</td></tr>
<tr><td></td></tr>
<tr><td colspan=2><b>Empty strings:</b></td></tr>
<tr><td><code>^</code></td><td>at beginning of text or line (<code>m</code>=true)</td></tr>
<tr><td><code>$</code></td><td>at end of text (like <code>\z</code> not <code>\Z</code>) or line (<code>m</code>=true)</td></tr>
<tr><td><code>\A</code></td><td>at beginning of text</td></tr>
<tr><td><code>\b</code></td><td>at ASCII word boundary (<code>\w</code> on one side and <code>\W</code>, <code>\A</code>, or <code>\z</code> on the other)</td></tr>
<tr><td><code>\B</code></td><td>not at ASCII word boundary</td></tr>
<tr><td><code><font color=#808080>\G</font></code></td><td>at beginning of subtext being searched  <font size=-2>PCRE</font></td></tr>
<tr><td><code><font color=#808080>\G</font></code></td><td>at end of last match  <font size=-2>PERL</font></td></tr>
<tr><td><code><font color=#808080>\Z</font></code></td><td>at end of text, or before newline at end of text </td></tr>
<tr><td><code>\z</code></td><td>at end of text</td></tr>
<tr><td><code><font color=#808080>(?=re)</font></code></td><td>before text matching <code>re</code> </td></tr>
<tr><td><code><font color=#808080>(?!re)</font></code></td><td>before text not matching <code>re</code> </td></tr>
<tr><td><code><font color=#808080>(?&lt;=re)</font></code></td><td>after text matching <code>re</code> </td></tr>
<tr><td><code><font color=#808080>(?&lt;!re)</font></code></td><td>after text not matching <code>re</code> </td></tr>
<tr><td><code><font color=#808080>re&amp;</font></code></td><td>before text matching <code>re</code>  <font size=-2>VIM</font></td></tr>
<tr><td><code><font color=#808080>re@=</font></code></td><td>before text matching <code>re</code>  <font size=-2>VIM</font></td></tr>
<tr><td><code><font color=#808080>re@!</font></code></td><td>before text not matching <code>re</code>  <font size=-2>VIM</font></td></tr>
<tr><td><code><font color=#808080>re@&lt;=</font></code></td><td>after text matching <code>re</code>  <font size=-2>VIM</font></td></tr>
<tr><td><code><font color=#808080>re@&lt;!</font></code></td><td>after text not matching <code>re</code>  <font size=-2>VIM</font></td></tr>
<tr><td><code><font color=#808080>\zs</font></code></td><td>sets start of match (= \K)  <font size=-2>VIM</font></td></tr>
<tr><td><code><font color=#808080>\ze</font></code></td><td>sets end of match  <font size=-2>VIM</font></td></tr>
<tr><td><code><font color=#808080>\%^</font></code></td><td>beginning of file  <font size=-2>VIM</font></td></tr>
<tr><td><code><font color=#808080>\%$</font></code></td><td>end of file  <font size=-2>VIM</font></td></tr>
<tr><td><code><font color=#808080>\%V</font></code></td><td>on screen  <font size=-2>VIM</font></td></tr>
<tr><td><code><font color=#808080>\%#</font></code></td><td>cursor position  <font size=-2>VIM</font></td></tr>
<tr><td><code><font color=#808080>\%'m</font></code></td><td>mark <code>m</code> position  <font size=-2>VIM</font></td></tr>
<tr><td><code><font color=#808080>\%23l</font></code></td><td>in line 23  <font size=-2>VIM</font></td></tr>
<tr><td><code><font color=#808080>\%23c</font></code></td><td>in column 23  <font size=-2>VIM</font></td></tr>
<tr><td><code><font color=#808080>\%23v</font></code></td><td>in virtual column 23  <font size=-2>VIM</font></td></tr>
<tr><td></td></tr>
<tr><td colspan=2><b>Escape sequences:</b></td></tr>
<tr><td><code>\a</code></td><td>bell (≡ <code>\007</code>)</td></tr>
<tr><td><code>\f</code></td><td>form feed (≡ <code>\014</code>)</td></tr>
<tr><td><code>\t</code></td><td>horizontal tab (≡ <code>\011</code>)</td></tr>
<tr><td><code>\n</code></td><td>newline (≡ <code>\012</code>)</td></tr>
<tr><td><code>\r</code></td><td>carriage return (≡ <code>\015</code>)</td></tr>
<tr><td><code>\v</code></td><td>vertical tab character (≡ <code>\013</code>)</td></tr>
<tr><td><code>\*</code></td><td>literal <code>*</code>, for any punctuation character <code>*</code></td></tr>
<tr><td><code>\123</code></td><td>octal character code (up to three digits)</td></tr>
<tr><td><code>\x7F</code></td><td>hex character code (exactly two digits)</td></tr>
<tr><td><code>\x{10FFFF}</code></td><td>hex character code</td></tr>
<tr><td><code>\C</code></td><td>match a single byte even in UTF-8 mode</td></tr>
<tr><td><code>\Q...\E</code></td><td>literal text <code>...</code> even if <code>...</code> has punctuation</td></tr>
<tr><td></td></tr>
<tr><td><code><font color=#808080>\1</font></code></td><td>backreference </td></tr>
<tr><td><code><font color=#808080>\b</font></code></td><td>backspace  (use <code>\010</code>)</td></tr>
<tr><td><code><font color=#808080>\cK</font></code></td><td>control char ^K  (use <code>\001</code> etc)</td></tr>
<tr><td><code><font color=#808080>\e</font></code></td><td>escape  (use <code>\033</code>)</td></tr>
<tr><td><code><font color=#808080>\g1</font></code></td><td>backreference </td></tr>
<tr><td><code><font color=#808080>\g{1}</font></code></td><td>backreference </td></tr>
<tr><td><code><font color=#808080>\g{+1}</font></code></td><td>backreference </td></tr>
<tr><td><code><font color=#808080>\g{-1}</font></code></td><td>backreference </td></tr>
<tr><td><code><font color=#808080>\g{name}</font></code></td><td>named backreference </td></tr>
<tr><td><code><font color=#808080>\g&lt;name&gt;</font></code></td><td>subroutine call </td></tr>
<tr><td><code><font color=#808080>\g'name'</font></code></td><td>subroutine call </td></tr>
<tr><td><code><font color=#808080>\k&lt;name&gt;</font></code></td><td>named backreference </td></tr>
<tr><td><code><font color=#808080>\k'name'</font></code></td><td>named backreference </td></tr>
<tr><td><code><font color=#808080>\lX</font></code></td><td>lowercase <code>X</code> </td></tr>
<tr><td><code><font color=#808080>\ux</font></code></td><td>uppercase <code>x</code> </td></tr>
<tr><td><code><font color=#808080>\L...\E</font></code></td><td>lowercase text <code>...</code> </td></tr>
<tr><td><code><font color=#808080>\K</font></code></td><td>reset beginning of <code>$0</code> </td></tr>
<tr><td><code><font color=#808080>\N{name}</font></code></td><td>named Unicode character </td></tr>
<tr><td><code><font color=#808080>\R</font></code></td><td>line break </td></tr>
<tr><td><code><font color=#808080>\U...\E</font></code></td><td>upper case text <code>...</code> </td></tr>
<tr><td><code><font color=#808080>\X</font></code></td><td>extended Unicode sequence </td></tr>
<tr><td></td></tr>
<tr><td><code><font color=#808080>\%d123</font></code></td><td>decimal character 123  <font size=-2>VIM</font></td></tr>
<tr><td><code><font color=#808080>\%xFF</font></code></td><td>hex character FF  <font size=-2>VIM</font></td></tr>
<tr><td><code><font color=#808080>\%o123</font></code></td><td>octal character 123  <font size=-2>VIM</font></td></tr>
<tr><td><code><font color=#808080>\%u1234</font></code></td><td>Unicode character 0x1234  <font size=-2>VIM</font></td></tr>
<tr><td><code><font color=#808080>\%U12345678</font></code></td><td>Unicode character 0x12345678  <font size=-2>VIM</font></td></tr>
<tr><td></td></tr>
<tr><td colspan=2><b>Character class elements:</b></td></tr>
<tr><td><code>x</code></td><td>single character</td></tr>
<tr><td><code>A-Z</code></td><td>character range (inclusive)</td></tr>
<tr><td><code>\d</code></td><td>Perl character class</td></tr>
<tr><td><code>[:foo:]</code></td><td>ASCII character class <code>foo</code></td></tr>
<tr><td><code>\p{Foo}</code></td><td>Unicode character class <code>Foo</code></td></tr>
<tr><td><code>\pF</code></td><td>Unicode character class <code>F</code> (one-letter name)</td></tr>
<tr><td></td></tr>
<tr><td colspan=2><b>Named character classes as character class elements:</b></td></tr>
<tr><td><code>[\d]</code></td><td>digits (≡ <code>\d</code>)</td></tr>
<tr><td><code>[^\d]</code></td><td>not digits (≡ <code>\D</code>)</td></tr>
<tr><td><code>[\D]</code></td><td>not digits (≡ <code>\D</code>)</td></tr>
<tr><td><code>[^\D]</code></td><td>not not digits (≡ <code>\d</code>)</td></tr>
<tr><td><code>[[:name:]]</code></td><td>named ASCII class inside character class (≡ <code>[:name:]</code>)</td></tr>
<tr><td><code>[^[:name:]]</code></td><td>named ASCII class inside negated character class (≡ <code>[:^name:]</code>)</td></tr>
<tr><td><code>[\p{Name}]</code></td><td>named Unicode property inside character class (≡ <code>\p{Name}</code>)</td></tr>
<tr><td><code>[^\p{Name}]</code></td><td>named Unicode property inside negated character class (≡ <code>\P{Name}</code>)</td></tr>
<tr><td></td></tr>
<tr><td colspan=2><b>Perl character classes (all ASCII-only):</b></td></tr>
<tr><td><code>\d</code></td><td>digits (≡ <code>[0-9]</code>)</td></tr>
<tr><td><code>\D</code></td><td>not digits (≡ <code>[^0-9]</code>)</td></tr>
<tr><td><code>\s</code></td><td>whitespace (≡ <code>[\t\n\f\r ]</code>)</td></tr>
<tr><td><code>\S</code></td><td>not whitespace (≡ <code>[^\t\n\f\r ]</code>)</td></tr>
<tr><td><code>\w</code></td><td>word characters (≡ <code>[0-9A-Za-z_]</code>)</td></tr>
<tr><td><code>\W</code></td><td>not word characters (≡ <code>[^0-9A-Za-z_]</code>)</td></tr>
<tr><td></td></tr>
<tr><td><code><font color=#808080>\h</font></code></td><td>horizontal space </td></tr>
<tr><td><code><font color=#808080>\H</font></code></td><td>not horizontal space </td></tr>
<tr><td><code><font color=#808080>\v</font></code></td><td>vertical space </td></tr>
<tr><td><code><font color=#808080>\V</font></code></td><td>not vertical space </td></tr>
<tr><td></td></tr>
<tr><td colspan=2><b>ASCII character classes:</b></td></tr>
<tr><td><code>[[:alnum:]]</code></td><td>alphanumeric (≡ <code>[0-9A-Za-z]</code>)</td></tr>
<tr><td><code>[[:alpha:]]</code></td><td>alphabetic (≡ <code>[A-Za-z]</code>)</td></tr>
<tr><td><code>[[:ascii:]]</code></td><td>ASCII (≡ <code>[\x00-\x7F]</code>)</td></tr>
<tr><td><code>[[:blank:]]</code></td><td>blank (≡ <code>[\t ]</code>)</td></tr>
<tr><td><code>[[:cntrl:]]</code></td><td>control (≡ <code>[\x00-\x1F\x7F]</code>)</td></tr>
<tr><td><code>[[:digit:]]</code></td><td>digits (≡ <code>[0-9]</code>)</td></tr>
<tr><td><code>[[:graph:]]</code></td><td>graphical (≡ <code>[!-~] == [A-Za-z0-9!"#$%&amp;'()*+,\-./:;&lt;=&gt;?@[\\\]^_`{|}~]</code>)</td></tr>
<tr><td><code>[[:lower:]]</code></td><td>lower case (≡ <code>[a-z]</code>)</td></tr>
<tr><td><code>[[:print:]]</code></td><td>printable (≡ <code>[ -~] == [ [:graph:]]</code>)</td></tr>
<tr><td><code>[[:punct:]]</code></td><td>punctuation (≡ <code>[!-/:-@[-`{-~]</code>)</td></tr>
<tr><td><code>[[:space:]]</code></td><td>whitespace (≡ <code>[\t\n\v\f\r ]</code>)</td></tr>
<tr><td><code>[[:upper:]]</code></td><td>upper case (≡ <code>[A-Z]</code>)</td></tr>
<tr><td><code>[[:word:]]</code></td><td>word characters (≡ <code>[0-9A-Za-z_]</code>)</td></tr>
<tr><td><code>[[:xdigit:]]</code></td><td>hex digit (≡ <code>[0-9A-Fa-f]</code>)</td></tr>
<tr><td></td></tr>
<tr><td colspan=2><b>Unicode character class names--general category:</b></td></tr>
<tr><td><code>C</code></td><td>other</td></tr>
<tr><td><code>Cc</code></td><td>control</td></tr>
<tr><td><code>Cf</code></td><td>format</td></tr>
<tr><td><code><font color=#808080>Cn</font></code></td><td>unassigned code points </td></tr>
<tr><td><code>Co</code></td><td>private use</td></tr>
<tr><td><code>Cs</code></td><td>surrogate</td></tr>
<tr><td><code>L</code></td><td>letter</td></tr>
<tr><td><code><font color=#808080>LC</font></code></td><td>cased letter </td></tr>
<tr><td><code><font color=#808080>L&amp;</font></code></td><td>cased letter </td></tr>
<tr><td><code>Ll</code></td><td>lowercase letter</td></tr>
<tr><td><code>Lm</code></td><td>modifier letter</td></tr>
<tr><td><code>Lo</code></td><td>other letter</td></tr>
<tr><td><code>Lt</code></td><td>titlecase letter</td></tr>
<tr><td><code>Lu</code></td><td>uppercase letter</td></tr>
<tr><td><code>M</code></td><td>mark</td></tr>
<tr><td><code>Mc</code></td><td>spacing mark</td></tr>
<tr><td><code>Me</code></td><td>enclosing mark</td></tr>
<tr><td><code>Mn</code></td><td>non-spacing mark</td></tr>
<tr><td><code>N</code></td><td>number</td></tr>
<tr><td><code>Nd</code></td><td>decimal number</td></tr>
<tr><td><code>Nl</code></td><td>letter number</td></tr>
<tr><td><code>No</code></td><td>other number</td></tr>
<tr><td><code>P</code></td><td>punctuation</td></tr>
<tr><td><code>Pc</code></td><td>connector punctuation</td></tr>
<tr><td><code>Pd</code></td><td>dash punctuation</td></tr>
<tr><td><code>Pe</code></td><td>close punctuation</td></tr>
<tr><td><code>Pf</code></td><td>final punctuation</td></tr>
<tr><td><code>Pi</code></td><td>initial punctuation</td></tr>
<tr><td><code>Po</code></td><td>other punctuation</td></tr>
<tr><td><code>Ps</code></td><td>open punctuation</td></tr>
<tr><td><code>S</code></td><td>symbol</td></tr>
<tr><td><code>Sc</code></td><td>currency symbol</td></tr>
<tr><td><code>Sk</code></td><td>modifier symbol</td></tr>
<tr><td><code>Sm</code></td><td>math symbol</td></tr>
<tr><td><code>So</code></td><td>other symbol</td></tr>
<tr><td><code>Z</code></td><td>separator</td></tr>
<tr><td><code>Zl</code></td><td>line separator</td></tr>
<tr><td><code>Zp</code></td><td>paragraph separator</td></tr>
<tr><td><code>Zs</code></td><td>space separator</td></tr>
<tr><td></td></tr>
<tr><td colspan=2><b>Unicode character class names--scripts:</b></td></tr>
<tr><td colspan=2>Adlam</td></tr>
<tr><td colspan=2>Ahom</td></tr>
<tr><td colspan=2>Anatolian_Hieroglyphs</td></tr>
<tr><td colspan=2>Arabic</td></tr>
<tr><td colspan=2>Armenian</td></tr>
<tr><td colspan=2>Avestan</td></tr>
<tr><td colspan=2>Balinese</td></tr>
<tr><td colspan=2>Bamum</td></tr>
<tr><td colspan=2>Bassa_Vah</td></tr>
<tr><td colspan=2>Batak</td></tr>
<tr><td colspan=2>Bengali</td></tr>
<tr><td colspan=2>Bhaiksuki</td></tr>
<tr><td colspan=2>Bopomofo</td></tr>
<tr><td colspan=2>Brahmi</td></tr>
<tr><td colspan=2>Braille</td></tr>
<tr><td colspan=2>Buginese</td></tr>
<tr><td colspan=2>Buhid</td></tr>
<tr><td colspan=2>Canadian_Aboriginal</td></tr>
<tr><td colspan=2>Carian</td></tr>
<tr><td colspan=2>Caucasian_Albanian</td></tr>
<tr><td colspan=2>Chakma</td></tr>
<tr><td colspan=2>Cham</td></tr>
<tr><td colspan=2>Cherokee</td></tr>
<tr><td colspan=2>Chorasmian</td></tr>
<tr><td colspan=2>Common</td></tr>
<tr><td colspan=2>Coptic</td></tr>
<tr><td colspan=2>Cuneiform</td></tr>
<tr><td colspan=2>Cypriot</td></tr>
<tr><td colspan=2>Cypro_Minoan</td></tr>
<tr><td colspan=2>Cyrillic</td></tr>
<tr><td colspan=2>Deseret</td></tr>
<tr><td colspan=2>Devanagari</td></tr>
<tr><td colspan=2>Dives_Akuru</td></tr>
<tr><td colspan=2>Dogra</td></tr>
<tr><td colspan=2>Duployan</td></tr>
<tr><td colspan=2>Egyptian_Hieroglyphs</td></tr>
<tr><td colspan=2>Elbasan</td></tr>
<tr><td colspan=2>Elymaic</td></tr>
<tr><td colspan=2>Ethiopic</td></tr>
<tr><td colspan=2>Georgian</td></tr>
<tr><td colspan=2>Glagolitic</td></tr>
<tr><td colspan=2>Gothic</td></tr>
<tr><td colspan=2>Grantha</td></tr>
<tr><td colspan=2>Greek</td></tr>
<tr><td colspan=2>Gujarati</td></tr>
<tr><td colspan=2>Gunjala_Gondi</td></tr>
<tr><td colspan=2>Gurmukhi</td></tr>
<tr><td colspan=2>Han</td></tr>
<tr><td colspan=2>Hangul</td></tr>
<tr><td colspan=2>Hanifi_Rohingya</td></tr>
<tr><td colspan=2>Hanunoo</td></tr>
<tr><td colspan=2>Hatran</td></tr>
<tr><td colspan=2>Hebrew</td></tr>
<tr><td colspan=2>Hiragana</td></tr>
<tr><td colspan=2>Imperial_Aramaic</td></tr>
<tr><td colspan=2>Inherited</td></tr>
<tr><td colspan=2>Inscriptional_Pahlavi</td></tr>
<tr><td colspan=2>Inscriptional_Parthian</td></tr>
<tr><td colspan=2>Javanese</td></tr>
<tr><td colspan=2>Kaithi</td></tr>
<tr><td colspan=2>Kannada</td></tr>
<tr><td colspan=2>Katakana</td></tr>
<tr><td colspan=2>Kawi</td></tr>
<tr><td colspan=2>Kayah_Li</td></tr>
<tr><td colspan=2>Kharoshthi</td></tr>
<tr><td colspan=2>Khitan_Small_Script</td></tr>
<tr><td colspan=2>Khmer</td></tr>
<tr><td colspan=2>Khojki</td></tr>
<tr><td colspan=2>Khudawadi</td></tr>
<tr><td colspan=2>Lao</td></tr>
<tr><td colspan=2>Latin</td></tr>
<tr><td colspan=2>Lepcha</td></tr>
<tr><td colspan=2>Limbu</td></tr>
<tr><td colspan=2>Linear_A</td></tr>
<tr><td colspan=2>Linear_B</td></tr>
<tr><td colspan=2>Lisu</td></tr>
<tr><td colspan=2>Lycian</td></tr>
<tr><td colspan=2>Lydian</td></tr>
<tr><td colspan=2>Mahajani</td></tr>
<tr><td colspan=2>Makasar</td></tr>
<tr><td colspan=2>Malayalam</td></tr>
<tr><td colspan=2>Mandaic</td></tr>
<tr><td colspan=2>Manichaean</td></tr>
<tr><td colspan=2>Marchen</td></tr>
<tr><td colspan=2>Masaram_Gondi</td></tr>
<tr><td colspan=2>Medefaidrin</td></tr>
<tr><td colspan=2>Meetei_Mayek</td></tr>
<tr><td colspan=2>Mende_Kikakui</td></tr>
<tr><td colspan=2>Meroitic_Cursive</td></tr>
<tr><td colspan=2>Meroitic_Hieroglyphs</td></tr>
<tr><td colspan=2>Miao</td></tr>
<tr><td colspan=2>Modi</td></tr>
<tr><td colspan=2>Mongolian</td></tr>
<tr><td colspan=2>Mro</td></tr>
<tr><td colspan=2>Multani</td></tr>
<tr><td colspan=2>Myanmar</td></tr>
<tr><td colspan=2>Nabataean</td></tr>
<tr><td colspan=2>Nag_Mundari</td></tr>
<tr><td colspan=2>Nandinagari</td></tr>
<tr><td colspan=2>New_Tai_Lue</td></tr>
<tr><td colspan=2>Newa</td></tr>
<tr><td colspan=2>Nko</td></tr>
<tr><td colspan=2>Nushu</td></tr>
<tr><td colspan=2>Nyiakeng_Puachue_Hmong</td></tr>
<tr><td colspan=2>Ogham</td></tr>
<tr><td colspan=2>Ol_Chiki</td></tr>
<tr><td colspan=2>Old_Hungarian</td></tr>
<tr><td colspan=2>Old_Italic</td></tr>
<tr><td colspan=2>Old_North_Arabian</td></tr>
<tr><td colspan=2>Old_Permic</td></tr>
<tr><td colspan=2>Old_Persian</td></tr>
<tr><td colspan=2>Old_Sogdian</td></tr>
<tr><td colspan=2>Old_South_Arabian</td></tr>
<tr><td colspan=2>Old_Turkic</td></tr>
<tr><td colspan=2>Old_Uyghur</td></tr>
<tr><td colspan=2>Oriya</td></tr>
<tr><td colspan=2>Osage</td></tr>
<tr><td colspan=2>Osmanya</td></tr>
<tr><td colspan=2>Pahawh_Hmong</td></tr>
<tr><td colspan=2>Palmyrene</td></tr>
<tr><td colspan=2>Pau_Cin_Hau</td></tr>
<tr><td colspan=2>Phags_Pa</td></tr>
<tr><td colspan=2>Phoenician</td></tr>
<tr><td colspan=2>Psalter_Pahlavi</td></tr>
<tr><td colspan=2>Rejang</td></tr>
<tr><td colspan=2>Runic</td></tr>
<tr><td colspan=2>Samaritan</td></tr>
<tr><td colspan=2>Saurashtra</td></tr>
<tr><td colspan=2>Sharada</td></tr>
<tr><td colspan=2>Shavian</td></tr>
<tr><td colspan=2>Siddham</td></tr>
<tr><td colspan=2>SignWriting</td></tr>
<tr><td colspan=2>Sinhala</td></tr>
<tr><td colspan=2>Sogdian</td></tr>
<tr><td colspan=2>Sora_Sompeng</td></tr>
<tr><td colspan=2>Soyombo</td></tr>
<tr><td colspan=2>Sundanese</td></tr>
<tr><td colspan=2>Syloti_Nagri</td></tr>
<tr><td colspan=2>Syriac</td></tr>
<tr><td colspan=2>Tagalog</td></tr>
<tr><td colspan=2>Tagbanwa</td></tr>
<tr><td colspan=2>Tai_Le</td></tr>
<tr><td colspan=2>Tai_Tham</td></tr>
<tr><td colspan=2>Tai_Viet</td></tr>
<tr><td colspan=2>Takri</td></tr>
<tr><td colspan=2>Tamil</td></tr>
<tr><td colspan=2>Tangsa</td></tr>
<tr><td colspan=2>Tangut</td></tr>
<tr><td colspan=2>Telugu</td></tr>
<tr><td colspan=2>Thaana</td></tr>
<tr><td colspan=2>Thai</td></tr>
<tr><td colspan=2>Tibetan</td></tr>
<tr><td colspan=2>Tifinagh</td></tr>
<tr><td colspan=2>Tirhuta</td></tr>
<tr><td colspan=2>Toto</td></tr>
<tr><td colspan=2>Ugaritic</td></tr>
<tr><td colspan=2>Vai</td></tr>
<tr><td colspan=2>Vithkuqi</td></tr>
<tr><td colspan=2>Wancho</td></tr>
<tr><td colspan=2>Warang_Citi</td></tr>
<tr><td colspan=2>Yezidi</td></tr>
<tr><td colspan=2>Yi</td></tr>
<tr><td colspan=2>Zanabazar_Square</td></tr>
<tr><td></td></tr>
<tr><td colspan=2><b>Vim character classes:</b></td></tr>
<tr><td><code><font color=#808080>\i</font></code></td><td>identifier character  <font size=-2>VIM</font></td></tr>
<tr><td><code><font color=#808080>\I</font></code></td><td><code>\i</code> except digits  <font size=-2>VIM</font></td></tr>
<tr><td><code><font color=#808080>\k</font></code></td><td>keyword character  <font size=-2>VIM</font></td></tr>
<tr><td><code><font color=#808080>\K</font></code></td><td><code>\k</code> except digits  <font size=-2>VIM</font></td></tr>
<tr><td><code><font color=#808080>\f</font></code></td><td>file name character  <font size=-2>VIM</font></td></tr>
<tr><td><code><font color=#808080>\F</font></code></td><td><code>\f</code> except digits  <font size=-2>VIM</font></td></tr>
<tr><td><code><font color=#808080>\p</font></code></td><td>printable character  <font size=-2>VIM</font></td></tr>
<tr><td><code><font color=#808080>\P</font></code></td><td><code>\p</code> except digits  <font size=-2>VIM</font></td></tr>
<tr><td><code><font color=#808080>\s</font></code></td><td>whitespace character (≡ <code>[ \t]</code>)  <font size=-2>VIM</font></td></tr>
<tr><td><code><font color=#808080>\S</font></code></td><td>non-white space character (≡ <code>[^ \t]</code>)  <font size=-2>VIM</font></td></tr>
<tr><td><code>\d</code></td><td>digits (≡ <code>[0-9]</code>) <font size=-2>VIM</font></td></tr>
<tr><td><code>\D</code></td><td>not <code>\d</code> <font size=-2>VIM</font></td></tr>
<tr><td><code><font color=#808080>\x</font></code></td><td>hex digits (≡ <code>[0-9A-Fa-f]</code>)  <font size=-2>VIM</font></td></tr>
<tr><td><code><font color=#808080>\X</font></code></td><td>not <code>\x</code>  <font size=-2>VIM</font></td></tr>
<tr><td><code><font color=#808080>\o</font></code></td><td>octal digits (≡ <code>[0-7]</code>)  <font size=-2>VIM</font></td></tr>
<tr><td><code><font color=#808080>\O</font></code></td><td>not <code>\o</code>  <font size=-2>VIM</font></td></tr>
<tr><td><code>\w</code></td><td>word character <font size=-2>VIM</font></td></tr>
<tr><td><code>\W</code></td><td>not <code>\w</code> <font size=-2>VIM</font></td></tr>
<tr><td><code><font color=#808080>\h</font></code></td><td>head of word character  <font size=-2>VIM</font></td></tr>
<tr><td><code><font color=#808080>\H</font></code></td><td>not <code>\h</code>  <font size=-2>VIM</font></td></tr>
<tr><td><code><font color=#808080>\a</font></code></td><td>alphabetic  <font size=-2>VIM</font></td></tr>
<tr><td><code><font color=#808080>\A</font></code></td><td>not <code>\a</code>  <font size=-2>VIM</font></td></tr>
<tr><td><code><font color=#808080>\l</font></code></td><td>lowercase  <font size=-2>VIM</font></td></tr>
<tr><td><code><font color=#808080>\L</font></code></td><td>not lowercase  <font size=-2>VIM</font></td></tr>
<tr><td><code><font color=#808080>\u</font></code></td><td>uppercase  <font size=-2>VIM</font></td></tr>
<tr><td><code><font color=#808080>\U</font></code></td><td>not uppercase  <font size=-2>VIM</font></td></tr>
<tr><td><code><font color=#808080>\_x</font></code></td><td><code>\x</code> plus newline, for any <code>x</code>  <font size=-2>VIM</font></td></tr>
<tr><td></td></tr>
<tr><td colspan=2><b>Vim flags:</b></td></tr>
<tr><td><code><font color=#808080>\c</font></code></td><td>ignore case  <font size=-2>VIM</font></td></tr>
<tr><td><code><font color=#808080>\C</font></code></td><td>match case  <font size=-2>VIM</font></td></tr>
<tr><td><code><font color=#808080>\m</font></code></td><td>magic  <font size=-2>VIM</font></td></tr>
<tr><td><code><font color=#808080>\M</font></code></td><td>nomagic  <font size=-2>VIM</font></td></tr>
<tr><td><code><font color=#808080>\v</font></code></td><td>verymagic  <font size=-2>VIM</font></td></tr>
<tr><td><code><font color=#808080>\V</font></code></td><td>verynomagic  <font size=-2>VIM</font></td></tr>
<tr><td><code><font color=#808080>\Z</font></code></td><td>ignore differences in Unicode combining characters  <font size=-2>VIM</font></td></tr>
<tr><td></td></tr>
<tr><td colspan=2><b>Magic:</b></td></tr>
<tr><td><code><font color=#808080>(?{code})</font></code></td><td>arbitrary Perl code  <font size=-2>PERL</font></td></tr>
<tr><td><code><font color=#808080>(??{code})</font></code></td><td>postponed arbitrary Perl code  <font size=-2>PERL</font></td></tr>
<tr><td><code><font color=#808080>(?n)</font></code></td><td>recursive call to regexp capturing group <code>n</code> </td></tr>
<tr><td><code><font color=#808080>(?+n)</font></code></td><td>recursive call to relative group <code>+n</code> </td></tr>
<tr><td><code><font color=#808080>(?-n)</font></code></td><td>recursive call to relative group <code>-n</code> </td></tr>
<tr><td><code><font color=#808080>(?C)</font></code></td><td>PCRE callout  <font size=-2>PCRE</font></td></tr>
<tr><td><code><font color=#808080>(?R)</font></code></td><td>recursive call to entire regexp (≡ <code>(?0)</code>) </td></tr>
<tr><td><code><font color=#808080>(?&amp;name)</font></code></td><td>recursive call to named group </td></tr>
<tr><td><code><font color=#808080>(?P=name)</font></code></td><td>named backreference </td></tr>
<tr><td><code><font color=#808080>(?P&gt;name)</font></code></td><td>recursive call to named group </td></tr>
<tr><td><code><font color=#808080>(?(cond)true|false)</font></code></td><td>conditional branch </td></tr>
<tr><td><code><font color=#808080>(?(cond)true)</font></code></td><td>conditional branch </td></tr>
<tr><td><code><font color=#808080>(*ACCEPT)</font></code></td><td>make regexps more like Prolog </td></tr>
<tr><td><code><font color=#808080>(*COMMIT)</font></code></td><td></td></tr>
<tr><td><code><font color=#808080>(*F)</font></code></td><td></td></tr>
<tr><td><code><font color=#808080>(*FAIL)</font></code></td><td></td></tr>
<tr><td><code><font color=#808080>(*MARK)</font></code></td><td></td></tr>
<tr><td><code><font color=#808080>(*PRUNE)</font></code></td><td></td></tr>
<tr><td><code><font color=#808080>(*SKIP)</font></code></td><td></td></tr>
<tr><td><code><font color=#808080>(*THEN)</font></code></td><td></td></tr>
<tr><td><code><font color=#808080>(*ANY)</font></code></td><td>set newline convention </td></tr>
<tr><td><code><font color=#808080>(*ANYCRLF)</font></code></td><td></td></tr>
<tr><td><code><font color=#808080>(*CR)</font></code></td><td></td></tr>
<tr><td><code><font color=#808080>(*CRLF)</font></code></td><td></td></tr>
<tr><td><code><font color=#808080>(*LF)</font></code></td><td></td></tr>
<tr><td><code><font color=#808080>(*BSR_ANYCRLF)</font></code></td><td>set \R convention  <font size=-2>PCRE</font></td></tr>
<tr><td><code><font color=#808080>(*BSR_UNICODE)</font></code></td><td> <font size=-2>PCRE</font></td></tr>
<tr><td></td></tr>
</table>
</body>
</html>


================================================
FILE: doc/syntax.txt
================================================
RE2 regular expression syntax reference
-------------------------­-------­-----

Single characters:
.	any character, possibly including newline (s=true)
[xyz]	character class
[^xyz]	negated character class
\d	Perl character class
\D	negated Perl character class
[[:alpha:]]	ASCII character class
[[:^alpha:]]	negated ASCII character class
\pN	Unicode character class (one-letter name)
\p{Greek}	Unicode character class
\PN	negated Unicode character class (one-letter name)
\P{Greek}	negated Unicode character class

Composites:
xy	«x» followed by «y»
x|y	«x» or «y» (prefer «x»)

Repetitions:
x*	zero or more «x», prefer more
x+	one or more «x», prefer more
x?	zero or one «x», prefer one
x{n,m}	«n» or «n»+1 or ... or «m» «x», prefer more
x{n,}	«n» or more «x», prefer more
x{n}	exactly «n» «x»
x*?	zero or more «x», prefer fewer
x+?	one or more «x», prefer fewer
x??	zero or one «x», prefer zero
x{n,m}?	«n» or «n»+1 or ... or «m» «x», prefer fewer
x{n,}?	«n» or more «x», prefer fewer
x{n}?	exactly «n» «x»
x{}	(== x*) NOT SUPPORTED vim
x{-}	(== x*?) NOT SUPPORTED vim
x{-n}	(== x{n}?) NOT SUPPORTED vim
x=	(== x?) NOT SUPPORTED vim

Implementation restriction: The counting forms «x{n,m}», «x{n,}», and «x{n}»
reject forms that create a minimum or maximum repetition count above 1000.
Unlimited repetitions are not subject to this restriction.

Possessive repetitions:
x*+	zero or more «x», possessive NOT SUPPORTED
x++	one or more «x», possessive NOT SUPPORTED
x?+	zero or one «x», possessive NOT SUPPORTED
x{n,m}+	«n» or ... or «m» «x», possessive NOT SUPPORTED
x{n,}+	«n» or more «x», possessive NOT SUPPORTED
x{n}+	exactly «n» «x», possessive NOT SUPPORTED

Grouping:
(re)	numbered capturing group (submatch)
(?P<name>re)	named & numbered capturing group (submatch)
(?<name>re)	named & numbered capturing group (submatch)
(?'name're)	named & numbered capturing group (submatch) NOT SUPPORTED
(?:re)	non-capturing group
(?flags)	set flags within current group; non-capturing
(?flags:re)	set flags during re; non-capturing
(?#text)	comment NOT SUPPORTED
(?|x|y|z)	branch numbering reset NOT SUPPORTED
(?>re)	possessive match of «re» NOT SUPPORTED
re@>	possessive match of «re» NOT SUPPORTED vim
%(re)	non-capturing group NOT SUPPORTED vim

Flags:
i	case-insensitive (default false)
m	multi-line mode: «^» and «$» match begin/end line in addition to begin/end text (default false)
s	let «.» match «\n» (default false)
U	ungreedy: swap meaning of «x*» and «x*?», «x+» and «x+?», etc (default false)
Flag syntax is «xyz» (set) or «-xyz» (clear) or «xy-z» (set «xy», clear «z»).

Empty strings:
^	at beginning of text or line («m»=true)
$	at end of text (like «\z» not «\Z») or line («m»=true)
\A	at beginning of text
\b	at ASCII word boundary («\w» on one side and «\W», «\A», or «\z» on the other)
\B	not at ASCII word boundary
\G	at beginning of subtext being searched NOT SUPPORTED pcre
\G	at end of last match NOT SUPPORTED perl
\Z	at end of text, or before newline at end of text NOT SUPPORTED
\z	at end of text
(?=re)	before text matching «re» NOT SUPPORTED
(?!re)	before text not matching «re» NOT SUPPORTED
(?<=re)	after text matching «re» NOT SUPPORTED
(?<!re)	after text not matching «re» NOT SUPPORTED
re&	before text matching «re» NOT SUPPORTED vim
re@=	before text matching «re» NOT SUPPORTED vim
re@!	before text not matching «re» NOT SUPPORTED vim
re@<=	after text matching «re» NOT SUPPORTED vim
re@<!	after text not matching «re» NOT SUPPORTED vim
\zs	sets start of match (= \K) NOT SUPPORTED vim
\ze	sets end of match NOT SUPPORTED vim
\%^	beginning of file NOT SUPPORTED vim
\%$	end of file NOT SUPPORTED vim
\%V	on screen NOT SUPPORTED vim
\%#	cursor position NOT SUPPORTED vim
\%'m	mark «m» position NOT SUPPORTED vim
\%23l	in line 23 NOT SUPPORTED vim
\%23c	in column 23 NOT SUPPORTED vim
\%23v	in virtual column 23 NOT SUPPORTED vim

Escape sequences:
\a	bell (== \007)
\f	form feed (== \014)
\t	horizontal tab (== \011)
\n	newline (== \012)
\r	carriage return (== \015)
\v	vertical tab character (== \013)
\*	literal «*», for any punctuation character «*»
\123	octal character code (up to three digits)
\x7F	hex character code (exactly two digits)
\x{10FFFF}	hex character code
\C	match a single byte even in UTF-8 mode
\Q...\E	literal text «...» even if «...» has punctuation

\1	backreference NOT SUPPORTED
\b	backspace NOT SUPPORTED (use «\010»)
\cK	control char ^K NOT SUPPORTED (use «\001» etc)
\e	escape NOT SUPPORTED (use «\033»)
\g1	backreference NOT SUPPORTED
\g{1}	backreference NOT SUPPORTED
\g{+1}	backreference NOT SUPPORTED
\g{-1}	backreference NOT SUPPORTED
\g{name}	named backreference NOT SUPPORTED
\g<name>	subroutine call NOT SUPPORTED
\g'name'	subroutine call NOT SUPPORTED
\k<name>	named backreference NOT SUPPORTED
\k'name'	named backreference NOT SUPPORTED
\lX	lowercase «X» NOT SUPPORTED
\ux	uppercase «x» NOT SUPPORTED
\L...\E	lowercase text «...» NOT SUPPORTED
\K	reset beginning of «$0» NOT SUPPORTED
\N{name}	named Unicode character NOT SUPPORTED
\R	line break NOT SUPPORTED
\U...\E	upper case text «...» NOT SUPPORTED
\X	extended Unicode sequence NOT SUPPORTED

\%d123	decimal character 123 NOT SUPPORTED vim
\%xFF	hex character FF NOT SUPPORTED vim
\%o123	octal character 123 NOT SUPPORTED vim
\%u1234	Unicode character 0x1234 NOT SUPPORTED vim
\%U12345678	Unicode character 0x12345678 NOT SUPPORTED vim

Character class elements:
x	single character
A-Z	character range (inclusive)
\d	Perl character class
[:foo:]	ASCII character class «foo»
\p{Foo}	Unicode character class «Foo»
\pF	Unicode character class «F» (one-letter name)

Named character classes as character class elements:
[\d]	digits (== \d)
[^\d]	not digits (== \D)
[\D]	not digits (== \D)
[^\D]	not not digits (== \d)
[[:name:]]	named ASCII class inside character class (== [:name:])
[^[:name:]]	named ASCII class inside negated character class (== [:^name:])
[\p{Name}]	named Unicode property inside character class (== \p{Name})
[^\p{Name}]	named Unicode property inside negated character class (== \P{Name})

Perl character classes (all ASCII-only):
\d	digits (== [0-9])
\D	not digits (== [^0-9])
\s	whitespace (== [\t\n\f\r ])
\S	not whitespace (== [^\t\n\f\r ])
\w	word characters (== [0-9A-Za-z_])
\W	not word characters (== [^0-9A-Za-z_])

\h	horizontal space NOT SUPPORTED
\H	not horizontal space NOT SUPPORTED
\v	vertical space NOT SUPPORTED
\V	not vertical space NOT SUPPORTED

ASCII character classes:
[[:alnum:]]	alphanumeric (== [0-9A-Za-z])
[[:alpha:]]	alphabetic (== [A-Za-z])
[[:ascii:]]	ASCII (== [\x00-\x7F])
[[:blank:]]	blank (== [\t ])
[[:cntrl:]]	control (== [\x00-\x1F\x7F])
[[:digit:]]	digits (== [0-9])
[[:graph:]]	graphical (== [!-~] == [A-Za-z0-9!"#$%&'()*+,\-./:;<=>?@[\\\]^_`{|}~])
[[:lower:]]	lower case (== [a-z])
[[:print:]]	printable (== [ -~] == [ [:graph:]])
[[:punct:]]	punctuation (== [!-/:-@[-`{-~])
[[:space:]]	whitespace (== [\t\n\v\f\r ])
[[:upper:]]	upper case (== [A-Z])
[[:word:]]	word characters (== [0-9A-Za-z_])
[[:xdigit:]]	hex digit (== [0-9A-Fa-f])

Unicode character class names--general category:
C	other
Cc	control
Cf	format
Cn	unassigned code points NOT SUPPORTED
Co	private use
Cs	surrogate
L	letter
LC	cased letter NOT SUPPORTED
L&	cased letter NOT SUPPORTED
Ll	lowercase letter
Lm	modifier letter
Lo	other letter
Lt	titlecase letter
Lu	uppercase letter
M	mark
Mc	spacing mark
Me	enclosing mark
Mn	non-spacing mark
N	number
Nd	decimal number
Nl	letter number
No	other number
P	punctuation
Pc	connector punctuation
Pd	dash punctuation
Pe	close punctuation
Pf	final punctuation
Pi	initial punctuation
Po	other punctuation
Ps	open punctuation
S	symbol
Sc	currency symbol
Sk	modifier symbol
Sm	math symbol
So	other symbol
Z	separator
Zl	line separator
Zp	paragraph separator
Zs	space separator

Unicode character class names--scripts:
Adlam
Ahom
Anatolian_Hieroglyphs
Arabic
Armenian
Avestan
Balinese
Bamum
Bassa_Vah
Batak
Bengali
Bhaiksuki
Bopomofo
Brahmi
Braille
Buginese
Buhid
Canadian_Aboriginal
Carian
Caucasian_Albanian
Chakma
Cham
Cherokee
Chorasmian
Common
Coptic
Cuneiform
Cypriot
Cypro_Minoan
Cyrillic
Deseret
Devanagari
Dives_Akuru
Dogra
Duployan
Egyptian_Hieroglyphs
Elbasan
Elymaic
Ethiopic
Georgian
Glagolitic
Gothic
Grantha
Greek
Gujarati
Gunjala_Gondi
Gurmukhi
Han
Hangul
Hanifi_Rohingya
Hanunoo
Hatran
Hebrew
Hiragana
Imperial_Aramaic
Inherited
Inscriptional_Pahlavi
Inscriptional_Parthian
Javanese
Kaithi
Kannada
Katakana
Kawi
Kayah_Li
Kharoshthi
Khitan_Small_Script
Khmer
Khojki
Khudawadi
Lao
Latin
Lepcha
Limbu
Linear_A
Linear_B
Lisu
Lycian
Lydian
Mahajani
Makasar
Malayalam
Mandaic
Manichaean
Marchen
Masaram_Gondi
Medefaidrin
Meetei_Mayek
Mende_Kikakui
Meroitic_Cursive
Meroitic_Hieroglyphs
Miao
Modi
Mongolian
Mro
Multani
Myanmar
Nabataean
Nag_Mundari
Nandinagari
New_Tai_Lue
Newa
Nko
Nushu
Nyiakeng_Puachue_Hmong
Ogham
Ol_Chiki
Old_Hungarian
Old_Italic
Old_North_Arabian
Old_Permic
Old_Persian
Old_Sogdian
Old_South_Arabian
Old_Turkic
Old_Uyghur
Oriya
Osage
Osmanya
Pahawh_Hmong
Palmyrene
Pau_Cin_Hau
Phags_Pa
Phoenician
Psalter_Pahlavi
Rejang
Runic
Samaritan
Saurashtra
Sharada
Shavian
Siddham
SignWriting
Sinhala
Sogdian
Sora_Sompeng
Soyombo
Sundanese
Syloti_Nagri
Syriac
Tagalog
Tagbanwa
Tai_Le
Tai_Tham
Tai_Viet
Takri
Tamil
Tangsa
Tangut
Telugu
Thaana
Thai
Tibetan
Tifinagh
Tirhuta
Toto
Ugaritic
Vai
Vithkuqi
Wancho
Warang_Citi
Yezidi
Yi
Zanabazar_Square

Vim character classes:
\i	identifier character NOT SUPPORTED vim
\I	«\i» except digits NOT SUPPORTED vim
\k	keyword character NOT SUPPORTED vim
\K	«\k» except digits NOT SUPPORTED vim
\f	file name character NOT SUPPORTED vim
\F	«\f» except digits NOT SUPPORTED vim
\p	printable character NOT SUPPORTED vim
\P	«\p» except digits NOT SUPPORTED vim
\s	whitespace character (== [ \t]) NOT SUPPORTED vim
\S	non-white space character (== [^ \t]) NOT SUPPORTED vim
\d	digits (== [0-9]) vim
\D	not «\d» vim
\x	hex digits (== [0-9A-Fa-f]) NOT SUPPORTED vim
\X	not «\x» NOT SUPPORTED vim
\o	octal digits (== [0-7]) NOT SUPPORTED vim
\O	not «\o» NOT SUPPORTED vim
\w	word character vim
\W	not «\w» vim
\h	head of word character NOT SUPPORTED vim
\H	not «\h» NOT SUPPORTED vim
\a	alphabetic NOT SUPPORTED vim
\A	not «\a» NOT SUPPORTED vim
\l	lowercase NOT SUPPORTED vim
\L	not lowercase NOT SUPPORTED vim
\u	uppercase NOT SUPPORTED vim
\U	not uppercase NOT SUPPORTED vim
\_x	«\x» plus newline, for any «x» NOT SUPPORTED vim

Vim flags:
\c	ignore case NOT SUPPORTED vim
\C	match case NOT SUPPORTED vim
\m	magic NOT SUPPORTED vim
\M	nomagic NOT SUPPORTED vim
\v	verymagic NOT SUPPORTED vim
\V	verynomagic NOT SUPPORTED vim
\Z	ignore differences in Unicode combining characters NOT SUPPORTED vim

Magic:
(?{code})	arbitrary Perl code NOT SUPPORTED perl
(??{code})	postponed arbitrary Perl code NOT SUPPORTED perl
(?n)	recursive call to regexp capturing group «n» NOT SUPPORTED
(?+n)	recursive call to relative group «+n» NOT SUPPORTED
(?-n)	recursive call to relative group «-n» NOT SUPPORTED
(?C)	PCRE callout NOT SUPPORTED pcre
(?R)	recursive call to entire regexp (== (?0)) NOT SUPPORTED
(?&name)	recursive call to named group NOT SUPPORTED
(?P=name)	named backreference NOT SUPPORTED
(?P>name)	recursive call to named group NOT SUPPORTED
(?(cond)true|false)	conditional branch NOT SUPPORTED
(?(cond)true)	conditional branch NOT SUPPORTED
(*ACCEPT)	make regexps more like Prolog NOT SUPPORTED
(*COMMIT)	NOT SUPPORTED
(*F)	NOT SUPPORTED
(*FAIL)	NOT SUPPORTED
(*MARK)	NOT SUPPORTED
(*PRUNE)	NOT SUPPORTED
(*SKIP)	NOT SUPPORTED
(*THEN)	NOT SUPPORTED
(*ANY)	set newline convention NOT SUPPORTED
(*ANYCRLF)	NOT SUPPORTED
(*CR)	NOT SUPPORTED
(*CRLF)	NOT SUPPORTED
(*LF)	NOT SUPPORTED
(*BSR_ANYCRLF)	set \R convention NOT SUPPORTED pcre
(*BSR_UNICODE)	NOT SUPPORTED pcre



================================================
FILE: lib/git/commit-msg.hook
================================================
#!/bin/sh
# From Gerrit Code Review 2.2.1
#
# Part of Gerrit Code Review (http://code.google.com/p/gerrit/)
#
# Copyright (C) 2009 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

CHANGE_ID_AFTER="Bug|Issue"
MSG="$1"

# Check for, and add if missing, a unique Change-Id
#
add_ChangeId() {
	clean_message=`sed -e '
		/^diff --git a\/.*/{
			s///
			q
		}
		/^Signed-off-by:/d
		/^#/d
	' "$MSG" | git stripspace`
	if test -z "$clean_message"
	then
		return
	fi

	if grep -i '^Change-Id:' "$MSG" >/dev/null
	then
		return
	fi

	id=`_gen_ChangeId`
	perl -e '
		$MSG = shift;
		$id = shift;
		$CHANGE_ID_AFTER = shift;

		undef $/;
		open(I, $MSG); $_ = <I>; close I;
		s|^diff --git a/.*||ms;
		s|^#.*$||mg;
		exit unless $_;

		@message = split /\n/;
		$haveFooter = 0;
		$startFooter = @message;
		for($line = @message - 1; $line >= 0; $line--) {
			$_ = $message[$line];

			if (/^[a-zA-Z0-9-]+:/ && !m,^[a-z0-9-]+://,) {
				$haveFooter++;
				next;
			}
			next if /^[ []/;
			$startFooter = $line if ($haveFooter && /^\r?$/);
			last;
		}

		@footer = @message[$startFooter+1..@message];
		@message = @message[0..$startFooter];
		push(@footer, "") unless @footer;

		for ($line = 0; $line < @footer; $line++) {
			$_ = $footer[$line];
			next if /^($CHANGE_ID_AFTER):/i;
			last;
		}
		splice(@footer, $line, 0, "Change-Id: I$id");

		$_ = join("\n", @message, @footer);
		open(O, ">$MSG"); print O; close O;
	' "$MSG" "$id" "$CHANGE_ID_AFTER"
}
_gen_ChangeIdInput() {
	echo "tree `git write-tree`"
	if parent=`git rev-parse HEAD^0 2>/dev/null`
	then
		echo "parent $parent"
	fi
	echo "author `git var GIT_AUTHOR_IDENT`"
	echo "committer `git var GIT_COMMITTER_IDENT`"
	echo
	printf '%s' "$clean_message"
}
_gen_ChangeId() {
	_gen_ChangeIdInput |
	git hash-object -t commit --stdin
}


add_ChangeId


================================================
FILE: libre2.symbols
================================================
{
	global:
		# re2::RE2*
		_ZN3re23RE2*;
		_ZNK3re23RE2*;
		# re2::operator<<*
		_ZN3re2ls*;
		# re2::FilteredRE2*
		_ZN3re211FilteredRE2*;
		_ZNK3re211FilteredRE2*;
		# re2::re2_internal*
		_ZN3re212re2_internal*;
		_ZNK3re212re2_internal*;
	local:
		*;
};


================================================
FILE: libre2.symbols.darwin
================================================
# Linker doesn't like these unmangled:
# re2::RE2*
__ZN3re23RE2*
__ZNK3re23RE2*
# re2::operator<<*
__ZN3re2ls*
# re2::FilteredRE2*
__ZN3re211FilteredRE2*
__ZNK3re211FilteredRE2*
# re2::re2_internal*
__ZN3re212re2_internal*
__ZNK3re212re2_internal*


================================================
FILE: python/BUILD.bazel
================================================
# Copyright 2009 The RE2 Authors.  All Rights Reserved.
# Use of this source code is governed by a BSD-style
# license that can be found in the LICENSE file.

# Bazel (http://bazel.build/) BUILD file for RE2 Python.

load("@pybind11_bazel//:build_defs.bzl", "pybind_extension")
load("@rules_python//python:defs.bzl", "py_library", "py_test")

pybind_extension(
    name = "_re2",
    srcs = ["_re2.cc"],
    deps = [
        "//:re2",
        "@abseil-cpp//absl/strings",
    ],
)

py_library(
    name = "re2",
    srcs = ["re2.py"],
    data = [":_re2"],
    imports = ["."],
    visibility = ["//visibility:public"],
)

py_test(
    name = "re2_test",
    size = "small",
    srcs = ["re2_test.py"],
    deps = [
        ":re2",
        "@abseil-py//absl/testing:absltest",
        "@abseil-py//absl/testing:parameterized",
    ],
)

# These are implementation details for `setup.py`, so they can be
# named however we want. For now, they are named to be consistent
# with the `--cpu` flag values that they will eventually replace.

platform(
    name = "darwin_x86_64",
    constraint_values = [
        "@platforms//cpu:x86_64",
        "@platforms//os:macos",
    ],
)

platform(
    name = "darwin_arm64",
    constraint_values = [
        "@platforms//cpu:arm64",
        "@platforms//os:macos",
    ],
)

platform(
    name = "x64_x86_windows",
    constraint_values = [
        "@platforms//cpu:x86_32",
        "@platforms//os:windows",
    ],
)

platform(
    name = "x64_windows",
    constraint_values = [
        "@platforms//cpu:x86_64",
        "@platforms//os:windows",
    ],
)

platform(
    name = "arm64_windows",
    constraint_values = [
        "@platforms//cpu:arm64",
        "@platforms//os:windows",
    ],
)


================================================
FILE: python/README
================================================
Building requires Python 3 and pybind11 to be installed on your system.


================================================
FILE: python/_re2.cc
================================================
// Copyright 2019 The RE2 Authors.  All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

#include <stddef.h>
#include <sys/types.h>

#include <memory>
#include <stdexcept>
#include <string>
#include <tuple>
#include <utility>
#include <vector>

#include "absl/strings/string_view.h"
#include "pybind11/buffer_info.h"
#include "pybind11/gil.h"
#include "pybind11/pybind11.h"
#include "pybind11/pytypes.h"
#include "pybind11/stl.h"  // IWYU pragma: keep
#include "re2/filtered_re2.h"
#include "re2/re2.h"
#include "re2/set.h"

#ifdef _WIN32
#include <basetsd.h>
#define ssize_t SSIZE_T
#endif

namespace re2_python {

// This is conventional.
namespace py = pybind11;

// In terms of the pybind11 API, a py::buffer is merely a py::object that
// supports the buffer interface/protocol and you must explicitly request
// a py::buffer_info in order to access the actual bytes. Under the hood,
// the py::buffer_info manages a reference count to the py::buffer, so it
// must be constructed and subsequently destructed while holding the GIL.
static inline absl::string_view FromBytes(const py::buffer_info& bytes) {
  char* data = reinterpret_cast<char*>(bytes.ptr);
  ssize_t size = bytes.size;
  return absl::string_view(data, size);
}

static inline int OneCharLen(const char* ptr) {
  return "\1\1\1\1\1\1\1\1\1\1\1\1\2\2\3\4"[(*ptr & 0xFF) >> 4];
}

// Helper function for when Python encodes str to bytes and then needs to
// convert str offsets to bytes offsets. Assumes that text is valid UTF-8.
ssize_t CharLenToBytes(py::buffer buffer, ssize_t pos, ssize_t len) {
  auto bytes = buffer.request();
  auto text = FromBytes(bytes);
  auto ptr = text.data() + pos;
  auto end = text.data() + text.size();
  while (ptr < end && len > 0) {
    ptr += OneCharLen(ptr);
    --len;
  }
  return ptr - (text.data() + pos);
}

// Helper function for when Python decodes bytes to str and then needs to
// convert bytes offsets to str offsets. Assumes that text is valid UTF-8.
ssize_t BytesToCharLen(py::buffer buffer, ssize_t pos, ssize_t endpos) {
  auto bytes = buffer.request();
  auto text = FromBytes(bytes);
  auto ptr = text.data() + pos;
  auto end = text.data() + endpos;
  ssize_t len = 0;
  while (ptr < end) {
    ptr += OneCharLen(ptr);
    ++len;
  }
  return len;
}

std::unique_ptr<RE2> RE2InitShim(py::buffer buffer,
                                 const RE2::Options& options) {
  auto bytes = buffer.request();
  auto pattern = FromBytes(bytes);
  return std::make_unique<RE2>(pattern, options);
}

py::bytes RE2ErrorShim(const RE2& self) {
  // Return std::string as bytes. That is, without decoding to str.
  return self.error();
}

std::vector<std::pair<py::bytes, int>> RE2NamedCapturingGroupsShim(
    const RE2& self) {
  const int num_groups = self.NumberOfCapturingGroups();
  std::vector<std::pair<py::bytes, int>> groups;
  groups.reserve(num_groups);
  for (const auto& it : self.NamedCapturingGroups()) {
    groups.emplace_back(it.first, it.second);
  }
  return groups;
}

std::vector<int> RE2ProgramFanoutShim(const RE2& self) {
  std::vector<int> histogram;
  self.ProgramFanout(&histogram);
  return histogram;
}

std::vector<int> RE2ReverseProgramFanoutShim(const RE2& self) {
  std::vector<int> histogram;
  self.ReverseProgramFanout(&histogram);
  return histogram;
}

std::tuple<bool, py::bytes, py::bytes> RE2PossibleMatchRangeShim(
    const RE2& self, int maxlen) {
  std::string min, max;
  // Return std::string as bytes. That is, without decoding to str.
  return {self.PossibleMatchRange(&min, &max, maxlen), min, max};
}

std::vector<std::pair<ssize_t, ssize_t>> RE2MatchShim(const RE2& self,
                                                      RE2::Anchor anchor,
                                                      py::buffer buffer,
                                                      ssize_t pos,
                                                      ssize_t endpos) {
  auto bytes = buffer.request();
  auto text = FromBytes(bytes);
  const int num_groups = self.NumberOfCapturingGroups() + 1;  // need $0
  std::vector<absl::string_view> groups;
  groups.resize(num_groups);
  py::gil_scoped_release release_gil;
  if (!self.Match(text, pos, endpos, anchor, groups.data(), groups.size())) {
    // Ensure that groups are null before converting to spans!
    for (auto& it : groups) {
      it = absl::string_view();
    }
  }
  std::vector<std::pair<ssize_t, ssize_t>> spans;
  spans.reserve(num_groups);
  for (const auto& it : groups) {
    if (it.data() == NULL) {
      spans.emplace_back(-1, -1);
    } else {
      spans.emplace_back(it.data() - text.data(),
                         it.data() - text.data() + it.size());
    }
  }
  return spans;
}

py::bytes RE2QuoteMetaShim(py::buffer buffer) {
  auto bytes = buffer.request();
  auto pattern = FromBytes(bytes);
  // Return std::string as bytes. That is, without decoding to str.
  return RE2::QuoteMeta(pattern);
}

class Set {
 public:
  Set(RE2::Anchor anchor, const RE2::Options& options)
      : set_(options, anchor) {}

  ~Set() = default;

  // Not copyable or movable.
  Set(const Set&) = delete;
  Set& operator=(const Set&) = delete;

  int Add(py::buffer buffer) {
    auto bytes = buffer.request();
    auto pattern = FromBytes(bytes);
    int index = set_.Add(pattern, /*error=*/NULL);  // -1 on error
    return index;
  }

  bool Compile() {
    // Compiling can fail.
    return set_.Compile();
  }

  std::vector<int> Match(py::buffer buffer) const {
    auto bytes = buffer.request();
    auto text = FromBytes(bytes);
    std::vector<int> matches;
    py::gil_scoped_release release_gil;
    set_.Match(text, &matches);
    return matches;
  }

 private:
  RE2::Set set_;
};

class Filter {
 public:
  Filter() = default;
  ~Filter() = default;

  // Not copyable or movable.
  Filter(const Filter&) = delete;
  Filter& operator=(const Filter&) = delete;

  int Add(py::buffer buffer, const RE2::Options& options) {
    auto bytes = buffer.request();
    auto pattern = FromBytes(bytes);
    int index = -1;  // not clobbered on error
    filter_.Add(pattern, options, &index);
    return index;
  }

  bool Compile() {
    std::vector<std::string> atoms;
    filter_.Compile(&atoms);
    RE2::Options options;
    options.set_literal(true);
    options.set_case_sensitive(false);
    set_ = std::make_unique<RE2::Set>(options, RE2::UNANCHORED);
    for (int i = 0; i < static_cast<int>(atoms.size()); ++i) {
      if (set_->Add(atoms[i], /*error=*/NULL) != i) {
        // Should never happen: the atom is a literal!
        py::pybind11_fail("set_->Add() failed");
      }
    }
    // Compiling can fail.
    return set_->Compile();
  }

  std::vector<int> Match(py::buffer buffer, bool potential) const {
    if (set_ == nullptr) {
      py::pybind11_fail("Match() called before compiling");
    }

    auto bytes = buffer.request();
    auto text = FromBytes(bytes);
    std::vector<int> atoms;
    py::gil_scoped_release release_gil;
    set_->Match(text, &atoms);
    std::vector<int> matches;
    if (potential) {
      filter_.AllPotentials(atoms, &matches);
    } else {
      filter_.AllMatches(text, atoms, &matches);
    }
    return matches;
  }

  const RE2& GetRE2(int index) const {
    return filter_.GetRE2(index);
  }

 private:
  re2::FilteredRE2 filter_;
  std::unique_ptr<RE2::Set> set_;
};

PYBIND11_MODULE(_re2, module) {
  // Translate exceptions thrown by py::pybind11_fail() into Python.
  py::register_local_exception<std::runtime_error>(module, "Error");

  module.def("CharLenToBytes", &CharLenToBytes);
  module.def("BytesToCharLen", &BytesToCharLen);

  // CLASSES
  //     class RE2
  //         enum Anchor
  //         class Options
  //             enum Encoding
  //     class Set
  //     class Filter
  py::class_<RE2> re2(module, "RE2");
  py::enum_<RE2::Anchor> anchor(re2, "Anchor");
  py::class_<RE2::Options> options(re2, "Options");
  py::enum_<RE2::Options::Encoding> encoding(options, "Encoding");
  py::class_<Set> set(module, "Set");
  py::class_<Filter> filter(module, "Filter");

  anchor.value("UNANCHORED", RE2::Anchor::UNANCHORED);
  anchor.value("ANCHOR_START", RE2::Anchor::ANCHOR_START);
  anchor.value("ANCHOR_BOTH", RE2::Anchor::ANCHOR_BOTH);

  encoding.value("UTF8", RE2::Options::Encoding::EncodingUTF8);
  encoding.value("LATIN1", RE2::Options::Encoding::EncodingLatin1);

  options.def(py::init<>())
      .def_property("max_mem",                          //
                    &RE2::Options::max_mem,             //
                    &RE2::Options::set_max_mem)         //
      .def_property("encoding",                         //
                    &RE2::Options::encoding,            //
                    &RE2::Options::set_encoding)        //
      .def_property("posix_syntax",                     //
                    &RE2::Options::posix_syntax,        //
                    &RE2::Options::set_posix_syntax)    //
      .def_property("longest_match",                    //
                    &RE2::Options::longest_match,       //
                    &RE2::Options::set_longest_match)   //
      .def_property("log_errors",                       //
                    &RE2::Options::log_errors,          //
                    &RE2::Options::set_log_errors)      //
      .def_property("literal",                          //
                    &RE2::Options::literal,             //
                    &RE2::Options::set_literal)         //
      .def_property("never_nl",                         //
                    &RE2::Options::never_nl,            //
                    &RE2::Options::set_never_nl)        //
      .def_property("dot_nl",                           //
                    &RE2::Options::dot_nl,              //
                    &RE2::Options::set_dot_nl)          //
      .def_property("never_capture",                    //
                    &RE2::Options::never_capture,       //
                    &RE2::Options::set_never_capture)   //
      .def_property("case_sensitive",                   //
                    &RE2::Options::case_sensitive,      //
                    &RE2::Options::set_case_sensitive)  //
      .def_property("perl_classes",                     //
                    &RE2::Options::perl_classes,        //
                    &RE2::Options::set_perl_classes)    //
      .def_property("word_boundary",                    //
                    &RE2::Options::word_boundary,       //
                    &RE2::Options::set_word_boundary)   //
      .def_property("one_line",                         //
                    &RE2::Options::one_line,            //
                    &RE2::Options::set_one_line);       //

  re2.def(py::init(&RE2InitShim))
      .def("ok", &RE2::ok)
      .def("error", &RE2ErrorShim)
      .def("options", &RE2::options)
      .def("NumberOfCapturingGroups", &RE2::NumberOfCapturingGroups)
      .def("NamedCapturingGroups", &RE2NamedCapturingGroupsShim)
      .def("ProgramSize", &RE2::ProgramSize)
      .def("ReverseProgramSize", &RE2::ReverseProgramSize)
      .def("ProgramFanout", &RE2ProgramFanoutShim)
      .def("ReverseProgramFanout", &RE2ReverseProgramFanoutShim)
      .def("PossibleMatchRange", &RE2PossibleMatchRangeShim)
      .def("Match", &RE2MatchShim)
      .def_static("QuoteMeta", &RE2QuoteMetaShim);

  set.def(py::init<RE2::Anchor, const RE2::Options&>())
      .def("Add", &Set::Add)
      .def("Compile", &Set::Compile)
      .def("Match", &Set::Match);

  filter.def(py::init<>())
      .def("Add", &Filter::Add)
      .def("Compile", &Filter::Compile)
      .def("Match", &Filter::Match)
      .def("GetRE2", &Filter::GetRE2,
           py::return_value_policy::reference_internal);
}

}  // namespace re2_python


================================================
FILE: python/re2.py
================================================
# Copyright 2019 The RE2 Authors.  All Rights Reserved.
# Use of this source code is governed by a BSD-style
# license that can be found in the LICENSE file.
r"""A drop-in replacement for the re module.

It uses RE2 under the hood, of course, so various PCRE features
(e.g. backreferences, look-around assertions) are not supported.
See https://github.com/google/re2/wiki/Syntax for the canonical
reference, but known syntactic "gotchas" relative to Python are:

  * PCRE supports \Z and \z; RE2 supports \z; Python supports \z,
    but calls it \Z. You must rewrite \Z to \z in pattern strings.

Known differences between this module's API and the re module's API:

  * The error class does not provide any error information as attributes.
  * The Options class replaces the re module's flags with RE2's options as
    gettable/settable properties. Please see re2.h for their documentation.
  * The pattern string and the input string do not have to be the same type.
    Any str will be encoded to UTF-8.
  * The pattern string cannot be str if the options specify Latin-1 encoding.

This module's LRU cache contains a maximum of 128 regular expression objects.
Each regular expression object's underlying RE2 object uses a maximum of 8MiB
of memory (by default). Hence, this module's LRU cache uses a maximum of 1GiB
of memory (by default), but in most cases, it should use much less than that.
"""

import codecs
import functools
import itertools

import _re2


# pybind11 translates C++ exceptions to Python exceptions.
# We use that same Python exception class for consistency.
error = _re2.Error


class Options(_re2.RE2.Options):

  __slots__ = ()

  NAMES = (
      'max_mem',
      'encoding',
      'posix_syntax',
      'longest_match',
      'log_errors',
      'literal',
      'never_nl',
      'dot_nl',
      'never_capture',
      'case_sensitive',
      'perl_classes',
      'word_boundary',
      'one_line',
  )


def compile(pattern, options=None):
  if isinstance(pattern, _Regexp):
    if options:
      raise error('pattern is already compiled, so '
                  'options may not be specified')
    return pattern
  options = options or Options()
  values = tuple(getattr(options, name) for name in Options.NAMES)
  return _Regexp._make(pattern, values)


def search(pattern, text, options=None):
  return compile(pattern, options=options).search(text)


def match(pattern, text, options=None):
  return compile(pattern, options=options).match(text)


def fullmatch(pattern, text, options=None):
  return compile(pattern, options=options).fullmatch(text)


def finditer(pattern, text, options=None):
  return compile(pattern, options=options).finditer(text)


def findall(pattern, text, options=None):
  return compile(pattern, options=options).findall(text)


def split(pattern, text, maxsplit=0, options=None):
  return compile(pattern, options=options).split(text, maxsplit)


def subn(pattern, repl, text, count=0, options=None):
  return compile(pattern, options=options).subn(repl, text, count)


def sub(pattern, repl, text, count=0, options=None):
  return compile(pattern, options=options).sub(repl, text, count)


def _encode(t):
  return t.encode(encoding='utf-8')


def _decode(b):
  return b.decode(encoding='utf-8')


def escape(pattern):
  if isinstance(pattern, str):
    encoded_pattern = _encode(pattern)
    escaped = _re2.RE2.QuoteMeta(encoded_pattern)
    decoded_escaped = _decode(escaped)
    return decoded_escaped
  else:
    escaped = _re2.RE2.QuoteMeta(pattern)
    return escaped


def purge():
  return _Regexp._make.cache_clear()


_Anchor = _re2.RE2.Anchor
_NULL_SPAN = (-1, -1)


class _Regexp(object):

  __slots__ = ('_pattern', '_regexp')

  @classmethod
  @functools.lru_cache(typed=True)
  def _make(cls, pattern, values):
    options = Options()
    for name, value in zip(Options.NAMES, values):
      setattr(options, name, value)
    return cls(pattern, options)

  def __init__(self, pattern, options):
    self._pattern = pattern
    if isinstance(self._pattern, str):
      if options.encoding == Options.Encoding.LATIN1:
        raise error('string type of pattern is str, but '
                    'encoding specified in options is LATIN1')
      encoded_pattern = _encode(self._pattern)
      self._regexp = _re2.RE2(encoded_pattern, options)
    else:
      self._regexp = _re2.RE2(self._pattern, options)
    if not self._regexp.ok():
      raise error(self._regexp.error())

  def __getstate__(self):
    options = {name: getattr(self.options, name) for name in Options.NAMES}
    return self._pattern, options

  def __setstate__(self, state):
    pattern, options = state
    values = tuple(options[name] for name in Options.NAMES)
    other = _Regexp._make(pattern, values)
    self._pattern = other._pattern
    self._regexp = other._regexp

  def _match(self, anchor, text, pos=None, endpos=None):
    pos = 0 if pos is None else max(0, min(pos, len(text)))
    endpos = len(text) if endpos is None else max(0, min(endpos, len(text)))
    if pos > endpos:
      return
    if isinstance(text, str):
      encoded_text = _encode(text)
      encoded_pos = _re2.CharLenToBytes(encoded_text, 0, pos)
      if endpos == len(text):
        # This is the common case.
        encoded_endpos = len(encoded_text)
      else:
        encoded_endpos = encoded_pos + _re2.CharLenToBytes(
            encoded_text, encoded_pos, endpos - pos)
      decoded_offsets = {0: 0}
      last_offset = 0
      while True:
        spans = self._regexp.Match(anchor, encoded_text, encoded_pos,
                                   encoded_endpos)
        if spans[0] == _NULL_SPAN:
          break

        # This algorithm is linear in the length of encoded_text. Specifically,
        # no matter how many groups there are for a given regular expression or
        # how many iterations through the loop there are for a given generator,
        # this algorithm uses a single, straightforward pass over encoded_text.
        offsets = sorted(set(itertools.chain(*spans)))
        if offsets[0] == -1:
          offsets = offsets[1:]
        # Discard the rest of the items because they are useless now - and we
        # could accumulate one item per str offset in the pathological case!
        decoded_offsets = {last_offset: decoded_offsets[last_offset]}
        for offset in offsets:
          decoded_offsets[offset] = (
              decoded_offsets[last_offset] +
              _re2.BytesToCharLen(encoded_text, last_offset, offset))
          last_offset = offset

        def decode(span):
          if span == _NULL_SPAN:
            return span
          return decoded_offsets[span[0]], decoded_offsets[span[1]]

        decoded_spans = [decode(span) for span in spans]
        yield _Match(self, text, pos, endpos, decoded_spans)
        if encoded_pos == encoded_endpos:
          break
        elif encoded_pos == spans[0][1]:
          # We matched the empty string at encoded_pos and would be stuck, so
          # in order to make forward progress, increment the str offset.
          encoded_pos += _re2.CharLenToBytes(encoded_text, encoded_pos, 1)
        else:
          encoded_pos = spans[0][1]
    else:
      while True:
        spans = self._regexp.Match(anchor, text, pos, endpos)
        if spans[0] == _NULL_SPAN:
          break
        yield _Match(self, text, pos, endpos, spans)
        if pos == endpos:
          break
        elif pos == spans[0][1]:
          # We matched the empty string at pos and would be stuck, so in order
          # to make forward progress, increment the bytes offset.
          pos += 1
        else:
          pos = spans[0][1]

  def search(self, text, pos=None, endpos=None):
    return next(self._match(_Anchor.UNANCHORED, text, pos, endpos), None)

  def match(self, text, pos=None, endpos=None):
    return next(self._match(_Anchor.ANCHOR_START, text, pos, endpos), None)

  def fullmatch(self, text, pos=None, endpos=None):
    return next(self._match(_Anchor.ANCHOR_BOTH, text, pos, endpos), None)

  def finditer(self, text, pos=None, endpos=None):
    return self._match(_Anchor.UNANCHORED, text, pos, endpos)

  def findall(self, text, pos=None, endpos=None):
    empty = type(text)()
    items = []
    for match in self.finditer(text, pos, endpos):
      if not self.groups:
        item = match.group()
      elif self.groups == 1:
        item = match.groups(default=empty)[0]
      else:
        item = match.groups(default=empty)
      items.append(item)
    return items

  def _split(self, cb, text, maxsplit=0):
    if maxsplit < 0:
      return [text], 0
    elif maxsplit > 0:
      matchiter = itertools.islice(self.finditer(text), maxsplit)
    else:
      matchiter = self.finditer(text)
    pieces = []
    end = 0
    numsplit = 0
    for match in matchiter:
      pieces.append(text[end:match.start()])
      pieces.extend(cb(match))
      end = match.end()
      numsplit += 1
    pieces.append(text[end:])
    return pieces, numsplit

  def split(self, text, maxsplit=0):
    cb = lambda match: [match[group] for group in range(1, self.groups + 1)]
    pieces, _ = self._split(cb, text, maxsplit)
    return pieces

  def subn(self, repl, text, count=0):
    cb = lambda match: [repl(match) if callable(repl) else match.expand(repl)]
    empty = type(text)()
    pieces, numsplit = self._split(cb, text, count)
    joined_pieces = empty.join(pieces)
    return joined_pieces, numsplit

  def sub(self, repl, text, count=0):
    joined_pieces, _ = self.subn(repl, text, count)
    return joined_pieces

  @property
  def pattern(self):
    return self._pattern

  @property
  def options(self):
    return self._regexp.options()

  @property
  def groups(self):
    return self._regexp.NumberOfCapturingGroups()

  @property
  def groupindex(self):
    groups = self._regexp.NamedCapturingGroups()
    if isinstance(self._pattern, str):
      decoded_groups = [(_decode(group), index) for group, index in groups]
      return dict(decoded_groups)
    else:
      return dict(groups)

  @property
  def programsize(self):
    return self._regexp.ProgramSize()

  @property
  def reverseprogramsize(self):
    return self._regexp.ReverseProgramSize()

  @property
  def programfanout(self):
    return self._regexp.ProgramFanout()

  @property
  def reverseprogramfanout(self):
    return self._regexp.ReverseProgramFanout()

  def possiblematchrange(self, maxlen):
    ok, min, max = self._regexp.PossibleMatchRange(maxlen)
    if not ok:
      raise error('failed to compute match range')
    return min, max


class _Match(object):

  __slots__ = ('_regexp', '_text', '_pos', '_endpos', '_spans')

  def __init__(self, regexp, text, pos, endpos, spans):
    self._regexp = regexp
    self._text = text
    self._pos = pos
    self._endpos = endpos
    self._spans = spans

  # Python prioritises three-digit octal numbers over group escapes.
  # For example, \100 should not be handled the same way as \g<10>0.
  _OCTAL_RE = compile('\\\\[0-7][0-7][0-7]')

  # Python supports \1 through \99 (inclusive) and \g<...> syntax.
  _GROUP_RE = compile('\\\\[1-9][0-9]?|\\\\g<\\w+>')

  @classmethod
  @functools.lru_cache(typed=True)
  def _split(cls, template):
    if isinstance(template, str):
      backslash = '\\'
    else:
      backslash = b'\\'
    empty = type(template)()
    pieces = [empty]
    index = template.find(backslash)
    while index != -1:
      piece, template = template[:index], template[index:]
      pieces[-1] += piece
      octal_match = cls._OCTAL_RE.match(template)
      group_match = cls._GROUP_RE.match(template)
      if (not octal_match) and group_match:
        index = group_match.end()
        piece, template = template[:index], template[index:]
        pieces.extend((piece, empty))
      else:
        # 2 isn't enough for \o, \x, \N, \u and \U escapes, but none of those
        # should contain backslashes, so break them here and then fix them at
        # the beginning of the next loop iteration or right before returning.
        index = 2
        piece, template = template[:index], template[index:]
        pieces[-1] += piece
      index = template.find(backslash)
    pieces[-1] += template
    return pieces

  def expand(self, template):
    if isinstance(template, str):
      unescape = codecs.unicode_escape_decode
    else:
      unescape = codecs.escape_decode
    empty = type(template)()
    # Make a copy so that we don't clobber the cached pieces!
    pieces = list(self._split(template))
    for index, piece in enumerate(pieces):
      if not index % 2:
        pieces[index], _ = unescape(piece)
      else:
        if len(piece) <= 3:  # \1 through \99 (inclusive)
          group = int(piece[1:])
        else:  # \g<...>
          group = piece[3:-1]
          try:
            group = int(group)
          except ValueError:
            pass
        pieces[index] = self.__getitem__(group) or empty
    joined_pieces = empty.join(pieces)
    return joined_pieces

  def __getitem__(self, group):
    if not isinstance(group, int):
      try:
        group = self._regexp.groupindex[group]
      except KeyError:
        raise IndexError('bad group name')
    if not 0 <= group <= self._regexp.groups:
      raise IndexError('bad group index')
    span = self._spans[group]
    if span == _NULL_SPAN:
      return None
    return self._text[span[0]:span[1]]

  def group(self, *groups):
    if not groups:
      groups = (0,)
    items = (self.__getitem__(group) for group in groups)
    return next(items) if len(groups) == 1 else tuple(items)

  def groups(self, default=None):
    items = []
    for group in range(1, self._regexp.groups + 1):
      item = self.__getitem__(group)
      items.append(default if item is None else item)
    return tuple(items)

  def groupdict(self, default=None):
    items = []
    for group, index in self._regexp.groupindex.items():
      item = self.__getitem__(index)
      items.append((group, default) if item is None else (group, item))
    return dict(items)

  def start(self, group=0):
    if not 0 <= group <= self._regexp.groups:
      raise IndexError('bad group index')
    return self._spans[group][0]

  def end(self, group=0):
    if not 0 <= group <= self._regexp.groups:
      raise IndexError('bad group index')
    return self._spans[group][1]

  def span(self, group=0):
    if not 0 <= group <= self._regexp.groups:
      raise IndexError('bad group index')
    return self._spans[group]

  @property
  def re(self):
    return self._regexp

  @property
  def string(self):
    return self._text

  @property
  def pos(self):
    return self._pos

  @property
  def endpos(self):
    return self._endpos

  @property
  def lastindex(self):
    max_end = -1
    max_group = None
    # We look for the rightmost right parenthesis by keeping the first group
    # that ends at max_end because that is the leftmost/outermost group when
    # there are nested groups!
    for group in range(1, self._regexp.groups + 1):
      end = self._spans[group][1]
      if max_end < end:
        max_end = end
        max_group = group
    return max_group

  @property
  def lastgroup(self):
    max_group = self.lastindex
    if not max_group:
      return None
    for group, index in self._regexp.groupindex.items():
      if max_group == index:
        return group
    return None


class Set(object):
  """A Pythonic wrapper around RE2::Set."""

  __slots__ = ('_set')

  def __init__(self, anchor, options=None):
    options = options or Options()
    self._set = _re2.Set(anchor, options)

  @classmethod
  def SearchSet(cls, options=None):
    return cls(_Anchor.UNANCHORED, options=options)

  @classmethod
  def MatchSet(cls, options=None):
    return cls(_Anchor.ANCHOR_START, options=options)

  @classmethod
  def FullMatchSet(cls, options=None):
    return cls(_Anchor.ANCHOR_BOTH, options=options)

  def Add(self, pattern):
    if isinstance(pattern, str):
      encoded_pattern = _encode(pattern)
      index = self._set.Add(encoded_pattern)
    else:
      index = self._set.Add(pattern)
    if index == -1:
      raise error('failed to add %r to Set' % pattern)
    return index

  def Compile(self):
    if not self._set.Compile():
      raise error('failed to compile Set')

  def Match(self, text):
    if isinstance(text, str):
      encoded_text = _encode(text)
      matches = self._set.Match(encoded_text)
    else:
      matches = self._set.Match(text)
    return matches or None


class Filter(object):
  """A Pythonic wrapper around FilteredRE2."""

  __slots__ = ('_filter', '_patterns')

  def __init__(self):
    self._filter = _re2.Filter()
    self._patterns = []

  def Add(self, pattern, options=None):
    options = options or Options()
    if isinstance(pattern, str):
      encoded_pattern = _encode(pattern)
      index = self._filter.Add(encoded_pattern, options)
    else:
      index = self._filter.Add(pattern, options)
    if index == -1:
      raise error('failed to add %r to Filter' % pattern)
    self._patterns.append(pattern)
    return index

  def Compile(self):
    if not self._filter.Compile():
      raise error('failed to compile Filter')

  def Match(self, text, potential=False):
    if isinstance(text, str):
      encoded_text = _encode(text)
      matches = self._filter.Match(encoded_text, potential)
    else:
      matches = self._filter.Match(text, potential)
    return matches or None

  def re(self, index):
    if not 0 <= index < len(self._patterns):
      raise IndexError('bad index')
    proxy = object.__new__(_Regexp)
    proxy._pattern = self._patterns[index]
    proxy._regexp = self._filter.GetRE2(index)
    return proxy


================================================
FILE: python/re2_test.py
================================================
# Copyright 2019 The RE2 Authors.  All Rights Reserved.
# Use of this source code is governed by a BSD-style
# license that can be found in the LICENSE file.
"""Tests for google3.third_party.re2.python.re2."""

import collections
import pickle
import re

from absl.testing import absltest
from absl.testing import parameterized
import re2


class OptionsTest(parameterized.TestCase):

  @parameterized.parameters(*re2.Options.NAMES)
  def test_option(self, name):
    options = re2.Options()
    value = getattr(options, name)
    if isinstance(value, re2.Options.Encoding):
      value = next(v for v in type(value).__members__.values() if v != value)
    elif isinstance(value, bool):
      value = not value
    elif isinstance(value, int):
      value = value + 1
    else:
      raise TypeError('option {!r}: {!r} {!r}'.format(name, type(value), value))
    setattr(options, name, value)
    self.assertEqual(value, getattr(options, name))


class Re2CompileTest(parameterized.TestCase):
  """Contains tests that apply to the re2 module only.

  We disagree with Python on the string types of group names,
  so there is no point attempting to verify consistency.
  """

  @parameterized.parameters(
      (u'(foo*)(?P<bar>qux+)', 2, [(u'bar', 2)]),
      (b'(foo*)(?P<bar>qux+)', 2, [(b'bar', 2)]),
      (u'(foo*)(?P<中文>qux+)', 2, [(u'中文', 2)]),
  )
  def test_compile(self, pattern, expected_groups, expected_groupindex):
    regexp = re2.compile(pattern)
    self.assertIs(regexp, re2.compile(pattern))  # cached
    self.assertIs(regexp, re2.compile(regexp))  # cached
    with self.assertRaisesRegex(re2.error,
                                ('pattern is already compiled, so '
                                 'options may not be specified')):
      options = re2.Options()
      options.log_errors = not options.log_errors
      re2.compile(regexp, options=options)
    self.assertIsNotNone(regexp.options)
    self.assertEqual(expected_groups, regexp.groups)
    self.assertDictEqual(dict(expected_groupindex), regexp.groupindex)

  def test_compile_with_options(self):
    options = re2.Options()
    options.max_mem = 100
    with self.assertRaisesRegex(re2.error, 'pattern too large'):
      re2.compile('.{1000}', options=options)

  def test_programsize_reverseprogramsize(self):
    regexp = re2.compile('a+b')
    self.assertEqual(7, regexp.programsize)
    self.assertEqual(7, regexp.reverseprogramsize)

  def test_programfanout_reverseprogramfanout(self):
    regexp = re2.compile('a+b')
    self.assertListEqual([1, 1], regexp.programfanout)
    self.assertListEqual([3], regexp.reverseprogramfanout)

  @parameterized.parameters(
      (u'abc', 0, None),
      (b'abc', 0, None),
      (u'abc', 10, (b'abc', b'abc')),
      (b'abc', 10, (b'abc', b'abc')),
      (u'ab*c', 10, (b'ab', b'ac')),
      (b'ab*c', 10, (b'ab', b'ac')),
      (u'ab+c', 10, (b'abb', b'abc')),
      (b'ab+c', 10, (b'abb', b'abc')),
      (u'ab?c', 10, (b'abc', b'ac')),
      (b'ab?c', 10, (b'abc', b'ac')),
      (u'.*', 10, (b'', b'\xf4\xbf\xbf\xc0')),
      (b'.*', 10, None),
      (u'\\C*', 10, None),
      (b'\\C*', 10, None),
  )
  def test_possiblematchrange(self, pattern, maxlen, expected_min_max):
    # For brevity, the string type of pattern determines the encoding.
    # It would otherwise be possible to have bytes with UTF8, but as per
    # the module docstring, it isn't permitted to have str with LATIN1.
    options = re2.Options()
    if isinstance(pattern, str):
      options.encoding = re2.Options.Encoding.UTF8
    else:
      options.encoding = re2.Options.Encoding.LATIN1
    regexp = re2.compile(pattern, options=options)
    if expected_min_max:
      self.assertEqual(expected_min_max, regexp.possiblematchrange(maxlen))
    else:
      with self.assertRaisesRegex(re2.error, 'failed to compute match range'):
        regexp.possiblematchrange(maxlen)


Params = collections.namedtuple(
    'Params', ('pattern', 'text', 'spans', 'search', 'match', 'fullmatch'))

PARAMS = [
    Params(u'\\d+', u'Hello, world.', None, False, False, False),
    Params(b'\\d+', b'Hello, world.', None, False, False, False),
    Params(u'\\s+', u'Hello, world.', [(6, 7)], True, False, False),
    Params(b'\\s+', b'Hello, world.', [(6, 7)], True, False, False),
    Params(u'\\w+', u'Hello, world.', [(0, 5)], True, True, False),
    Params(b'\\w+', b'Hello, world.', [(0, 5)], True, True, False),
    Params(u'(\\d+)?', u'Hello, world.', [(0, 0), (-1, -1)], True, True, False),
    Params(b'(\\d+)?', b'Hello, world.', [(0, 0), (-1, -1)], True, True, False),
    Params(u'youtube(_device|_md|_gaia|_multiday|_multiday_gaia)?',
           u'youtube_ads', [(0, 7), (-1, -1)], True, True, False),
    Params(b'youtube(_device|_md|_gaia|_multiday|_multiday_gaia)?',
           b'youtube_ads', [(0, 7), (-1, -1)], True, True, False),
]


def upper(match):
  return match.group().upper()


class ReRegexpTest(parameterized.TestCase):
  """Contains tests that apply to the re and re2 modules."""

  MODULE = re

  @parameterized.parameters((p.pattern,) for p in PARAMS)
  def test_pickle(self, pattern):
    regexp = self.MODULE.compile(pattern)
    rick = pickle.loads(pickle.dumps(regexp))
    self.assertEqual(regexp.pattern, rick.pattern)

  @parameterized.parameters(
      (p.pattern, p.text, (p.spans if p.search else None)) for p in PARAMS)
  def test_search(self, pattern, text, expected_spans):
    match = self.MODULE.search(pattern, text)
    if expected_spans is None:
      self.assertIsNone(match)
    else:
      spans = [match.span(group) for group in range(match.re.groups + 1)]
      self.assertListEqual(expected_spans, spans)

  def test_search_with_pos_and_endpos(self):
    regexp = self.MODULE.compile(u'.+')  # empty string NOT allowed
    text = u'I \u2665 RE2!'
    # Note that len(text) is the position of the empty string at the end of
    # text, so range() stops at len(text) + 1 in order to include len(text).
    for pos in range(len(text) + 1):
      for endpos in range(pos, len(text) + 1):
        match = regexp.search(text, pos=pos, endpos=endpos)
        if pos == endpos:
          self.assertIsNone(match)
        else:
          self.assertEqual(pos, match.pos)
          self.assertEqual(endpos, match.endpos)
          self.assertEqual(pos, match.start())
          self.assertEqual(endpos, match.end())
          self.assertTupleEqual((pos, endpos), match.span())

  def test_search_with_bogus_pos_and_endpos(self):
    regexp = self.MODULE.compile(u'.*')  # empty string allowed
    text = u'I \u2665 RE2!'

    match = regexp.search(text, pos=-100)
    self.assertEqual(0, match.pos)
    match = regexp.search(text, pos=100)
    self.assertEqual(8, match.pos)

    match = regexp.search(text, endpos=-100)
    self.assertEqual(0, match.endpos)
    match = regexp.search(text, endpos=100)
    self.assertEqual(8, match.endpos)

    match = regexp.search(text, pos=100, endpos=-100)
    self.assertIsNone(match)

  @parameterized.parameters(
      (p.pattern, p.text, (p.spans if p.match else None)) for p in PARAMS)
  def test_match(self, pattern, text, expected_spans):
    match = self.MODULE.match(pattern, text)
    if expected_spans is None:
      self.assertIsNone(match)
    else:
      spans = [match.span(group) for group in range(match.re.groups + 1)]
      self.assertListEqual(expected_spans, spans)

  @parameterized.parameters(
      (p.pattern, p.text, (p.spans if p.fullmatch else None)) for p in PARAMS)
  def test_fullmatch(self, pattern, text, expected_spans):
    match = self.MODULE.fullmatch(pattern, text)
    if expected_spans is None:
      self.assertIsNone(match)
    else:
      spans = [match.span(group) for group in range(match.re.groups + 1)]
      self.assertListEqual(expected_spans, spans)

  @parameterized.parameters(
      (u'', u'', [(0, 0)]),
      (b'', b'', [(0, 0)]),
      (u'', u'x', [(0, 0), (1, 1)]),
      (b'', b'x', [(0, 0), (1, 1)]),
      (u'', u'xy', [(0, 0), (1, 1), (2, 2)]),
      (b'', b'xy', [(0, 0), (1, 1), (2, 2)]),
      (u'.', u'xy', [(0, 1), (1, 2)]),
      (b'.', b'xy', [(0, 1), (1, 2)]),
      (u'x', u'xy', [(0, 1)]),
      (b'x', b'xy', [(0, 1)]),
      (u'y', u'xy', [(1, 2)]),
      (b'y', b'xy', [(1, 2)]),
      (u'z', u'xy', []),
      (b'z', b'xy', []),
      (u'\\w*', u'Hello, world.', [(0, 5), (5, 5), (6, 6), (7, 12), (12, 12),
                                   (13, 13)]),
      (b'\\w*', b'Hello, world.', [(0, 5), (5, 5), (6, 6), (7, 12), (12, 12),
                                   (13, 13)]),
  )
  def test_finditer(self, pattern, text, expected_matches):
    matches = [match.span() for match in self.MODULE.finditer(pattern, text)]
    self.assertListEqual(expected_matches, matches)

  @parameterized.parameters(
      (u'\\w\\w+', u'Hello, world.', [u'Hello', u'world']),
      (b'\\w\\w+', b'Hello, world.', [b'Hello', b'world']),
      (u'(\\w)\\w+', u'Hello, world.', [u'H', u'w']),
      (b'(\\w)\\w+', b'Hello, world.', [b'H', b'w']),
      (u'(\\w)(\\w+)', u'Hello, world.', [(u'H', u'ello'), (u'w', u'orld')]),
      (b'(\\w)(\\w+)', b'Hello, world.', [(b'H', b'ello'), (b'w', b'orld')]),
      (u'(\\w)(\\w+)?', u'Hello, w.', [(u'H', u'ello'), (u'w', u'')]),
      (b'(\\w)(\\w+)?', b'Hello, w.', [(b'H', b'ello'), (b'w', b'')]),
  )
  def test_findall(self, pattern, text, expected_matches):
    matches = self.MODULE.findall(pattern, text)
    self.assertListEqual(expected_matches, matches)

  @parameterized.parameters(
      (u'\\W+', u'Hello, world.', -1, [u'Hello, world.']),
      (b'\\W+', b'Hello, world.', -1, [b'Hello, world.']),
      (u'\\W+', u'Hello, world.', 0, [u'Hello', u'world', u'']),
      (b'\\W+', b'Hello, world.', 0, [b'Hello', b'world', b'']),
      (u'\\W+', u'Hello, world.', 1, [u'Hello', u'world.']),
      (b'\\W+', b'Hello, world.', 1, [b'Hello', b'world.']),
      (u'(\\W+)', u'Hello, world.', -1, [u'Hello, world.']),
      (b'(\\W+)', b'Hello, world.', -1, [b'Hello, world.']),
      (u'(\\W+)', u'Hello, world.', 0, [u'Hello', u', ', u'world', u'.', u'']),
      (b'(\\W+)', b'Hello, world.', 0, [b'Hello', b', ', b'world', b'.', b'']),
      (u'(\\W+)', u'Hello, world.', 1, [u'Hello', u', ', u'world.']),
      (b'(\\W+)', b'Hello, world.', 1, [b'Hello', b', ', b'world.']),
  )
  def test_split(self, pattern, text, maxsplit, expected_pieces):
    pieces = self.MODULE.split(pattern, text, maxsplit)
    self.assertListEqual(expected_pieces, pieces)

  @parameterized.parameters(
      (u'\\w+', upper, u'Hello, world.', -1, u'Hello, world.', 0),
      (b'\\w+', upper, b'Hello, world.', -1, b'Hello, world.', 0),
      (u'\\w+', upper, u'Hello, world.', 0, u'HELLO, WORLD.', 2),
      (b'\\w+', upper, b'Hello, world.', 0, b'HELLO, WORLD.', 2),
      (u'\\w+', upper, u'Hello, world.', 1, u'HELLO, world.', 1),
      (b'\\w+', upper, b'Hello, world.', 1, b'HELLO, world.', 1),
      (u'\\w+', u'MEEP', u'Hello, world.', -1, u'Hello, world.', 0),
      (b'\\w+', b'MEEP', b'Hello, world.', -1, b'Hello, world.', 0),
      (u'\\w+', u'MEEP', u'Hello, world.', 0, u'MEEP, MEEP.', 2),
      (b'\\w+', b'MEEP', b'Hello, world.', 0, b'MEEP, MEEP.', 2),
      (u'\\w+', u'MEEP', u'Hello, world.', 1, u'MEEP, world.', 1),
      (b'\\w+', b'MEEP', b'Hello, world.', 1, b'MEEP, world.', 1),
      (u'\\\\', u'\\\\\\\\', u'Hello,\\world.', 0, u'Hello,\\\\world.', 1),
      (b'\\\\', b'\\\\\\\\', b'Hello,\\world.', 0, b'Hello,\\\\world.', 1),
  )
  def test_subn_sub(self, pattern, repl, text, count, expected_joined_pieces,
                    expected_numsplit):
    joined_pieces, numsplit = self.MODULE.subn(pattern, repl, text, count)
    self.assertEqual(expected_joined_pieces, joined_pieces)
    self.assertEqual(expected_numsplit, numsplit)

    joined_pieces = self.MODULE.sub(pattern, repl, text, count)
    self.assertEqual(expected_joined_pieces, joined_pieces)


class Re2RegexpTest(ReRegexpTest):
  """Contains tests that apply to the re2 module only."""

  MODULE = re2

  def test_compile_with_latin1_encoding(self):
    options = re2.Options()
    options.encoding = re2.Options.Encoding.LATIN1
    with self.assertRaisesRegex(re2.error,
                                ('string type of pattern is str, but '
                                 'encoding specified in options is LATIN1')):
      re2.compile(u'.?', options=options)

    # ... whereas this is fine, of course.
    re2.compile(b'.?', options=options)

  @parameterized.parameters(
      (u'\\p{Lo}', u'\u0ca0_\u0ca0', [(0, 1), (2, 3)]),
      (b'\\p{Lo}', b'\xe0\xb2\xa0_\xe0\xb2\xa0', [(0, 3), (4, 7)]),
  )
  def test_finditer_with_utf8(self, pattern, text, expected_matches):
    matches = [match.span() for match in self.MODULE.finditer(pattern, text)]
    self.assertListEqual(expected_matches, matches)

  def test_purge(self):
    re2.compile('Goodbye, world.')
    self.assertGreater(re2._Regexp._make.cache_info().currsize, 0)
    re2.purge()
    self.assertEqual(re2._Regexp._make.cache_info().currsize, 0)

  def test_options(self):
    opt = re2.Options()
    opt.case_sensitive = False
    r = re2.compile('test', opt)
    self.assertIsNotNone(r.search('TEST'))
    self.assertIsNotNone(re2.search(r, 'TEST'))

class Re2EscapeTest(parameterized.TestCase):
  """Contains tests that apply to the re2 module only.

  We disagree with Python on the escaping of some characters,
  so there is no point attempting to verify consistency.
  """

  @parameterized.parameters(
      (u'a*b+c?', u'a\\*b\\+c\\?'),
      (b'a*b+c?', b'a\\*b\\+c\\?'),
  )
  def test_escape(self, pattern, expected_escaped):
    escaped = re2.escape(pattern)
    self.assertEqual(expected_escaped, escaped)


class ReMatchTest(parameterized.TestCase):
  """Contains tests that apply to the re and re2 modules."""

  MODULE = re

  def test_expand(self):
    pattern = u'(?P<S>[\u2600-\u26ff]+).*?(?P<P>[^\\s\\w]+)'
    text = u'I \u2665 RE2!\n'
    match = self.MODULE.search(pattern, text)

    self.assertEqual(u'\u2665\n!', match.expand(u'\\1\\n\\2'))
    self.assertEqual(u'\u2665\n!', match.expand(u'\\g<1>\\n\\g<2>'))
    self.assertEqual(u'\u2665\n!', match.expand(u'\\g<S>\\n\\g<P>'))
    self.assertEqual(u'\\1\\2\n\u2665!', match.expand(u'\\\\1\\\\2\\n\\1\\2'))

  def test_expand_with_octal(self):
    pattern = u'()()()()()()()()()(\\w+)'
    text = u'Hello, world.'
    match = self.MODULE.search(pattern, text)

    self.assertEqual(u'Hello\n', match.expand(u'\\g<0>\\n'))
    self.assertEqual(u'Hello\n', match.expand(u'\\g<10>\\n'))

    self.assertEqual(u'\x00\n', match.expand(u'\\0\\n'))
    self.assertEqual(u'\x00\n', match.expand(u'\\00\\n'))
    self.assertEqual(u'\x00\n', match.expand(u'\\000\\n'))
    self.assertEqual(u'\x000\n', match.expand(u'\\0000\\n'))

    self.assertEqual(u'\n', match.expand(u'\\1\\n'))
    self.assertEqual(u'Hello\n', match.expand(u'\\10\\n'))
    self.assertEqual(u'@\n', match.expand(u'\\100\\n'))
    self.assertEqual(u'@0\n', match.expand(u'\\1000\\n'))

  def test_getitem_group_groups_groupdict(self):
    pattern = u'(?P<S>[\u2600-\u26ff]+).*?(?P<P>[^\\s\\w]+)'
    text = u'Hello, world.\nI \u2665 RE2!\nGoodbye, world.\n'
    match = self.MODULE.search(pattern, text)

    self.assertEqual(u'\u2665 RE2!', match[0])
    self.assertEqual(u'\u2665', match[1])
    self.assertEqual(u'!', match[2])
    self.assertEqual(u'\u2665', match[u'S'])
    self.assertEqual(u'!', match[u'P'])

    self.assertEqual(u'\u2665 RE2!', match.group())
    self.assertEqual(u'\u2665 RE2!', match.group(0))
    self.assertEqual(u'\u2665', match.group(1))
    self.assertEqual(u'!', match.group(2))
    self.assertEqual(u'\u2665', match.group(u'S'))
    self.assertEqual(u'!', match.group(u'P'))

    self.assertTupleEqual((u'\u2665', u'!'), match.group(1, 2))
    self.assertTupleEqual((u'\u2665', u'!'), match.group(u'S', u'P'))
    self.assertTupleEqual((u'\u2665', u'!'), match.groups())
    self.assertDictEqual({u'S': u'\u2665', u'P': u'!'}, match.groupdict())

  def test_bogus_group_start_end_and_span(self):
    pattern = u'(?P<S>[\u2600-\u26ff]+).*?(?P<P>[^\\s\\w]+)'
    text = u'I \u2665 RE2!\n'
    match = self.MODULE.search(pattern, text)

    self.assertRaises(IndexError, match.group, -1)
    self.assertRaises(IndexError, match.group, 3)
    self.assertRaises(IndexError, match.group, 'X')

    self.assertRaises(IndexError, match.start, -1)
    self.assertRaises(IndexError, match.start, 3)

    self.assertRaises(IndexError, match.end, -1)
    self.assertRaises(IndexError, match.end, 3)

    self.assertRaises(IndexError, match.span, -1)
    self.assertRaises(IndexError, match.span, 3)

  @parameterized.parameters(
      (u'((a)(b))((c)(d))', u'foo bar qux', None, None),
      (u'(?P<one>(a)(b))((c)(d))', u'foo abcd qux', 4, None),
      (u'(?P<one>(a)(b))(?P<four>(c)(d))', u'foo abcd qux', 4, 'four'),
  )
  def test_lastindex_lastgroup(self, pattern, text, expected_lastindex,
                               expected_lastgroup):
    match = self.MODULE.search(pattern, text)
    if expected_lastindex is None:
      self.assertIsNone(match)
    else:
      self.assertEqual(expected_lastindex, match.lastindex)
      self.assertEqual(expected_lastgroup, match.lastgroup)


class Re2MatchTest(ReMatchTest):
  """Contains tests that apply to the re2 module only."""

  MODULE = re2


class SetTest(absltest.TestCase):

  def test_search(self):
    s = re2.Set.SearchSet()
    self.assertEqual(0, s.Add('\\d+'))
    self.assertEqual(1, s.Add('\\s+'))
    self.assertEqual(2, s.Add('\\w+'))
    self.assertRaises(re2.error, s.Add, '(MEEP')
    s.Compile()
    self.assertItemsEqual([1, 2], s.Match('Hello, world.'))

  def test_match(self):
    s = re2.Set.MatchSet()
    self.assertEqual(0, s.Add('\\d+'))
    self.assertEqual(1, s.Add('\\s+'))
    self.assertEqual(2, s.Add('\\w+'))
    self.assertRaises(re2.error, s.Add, '(MEEP')
    s.Compile()
    self.assertItemsEqual([2], s.Match('Hello, world.'))

  def test_fullmatch(self):
    s = re2.Set.FullMatchSet()
    self.assertEqual(0, s.Add('\\d+'))
    self.assertEqual(1, s.Add('\\s+'))
    self.assertEqual(2, s.Add('\\w+'))
    self.assertRaises(re2.error, s.Add, '(MEEP')
    s.Compile()
    self.assertIsNone(s.Match('Hello, world.'))


class FilterTest(absltest.TestCase):

  def test_match(self):
    f = re2.Filter()
    self.assertEqual(0, f.Add('Hello, \\w+\\.'))
    self.assertEqual(1, f.Add('\\w+, world\\.'))
    self.assertEqual(2, f.Add('Goodbye, \\w+\\.'))
    self.assertRaises(re2.error, f.Add, '(MEEP')
    f.Compile()
    self.assertItemsEqual([0, 1], f.Match('Hello, world.', potential=True))
    self.assertItemsEqual([0, 1], f.Match('HELLO, WORLD.', potential=True))
    self.assertItemsEqual([0, 1], f.Match('Hello, world.'))
    self.assertIsNone(f.Match('HELLO, WORLD.'))

    self.assertRaises(IndexError, f.re, -1)
    self.assertRaises(IndexError, f.re, 3)
    self.assertEqual('Goodbye, \\w+\\.', f.re(2).pattern)
    # Verify whether the underlying RE2 object is usable.
    self.assertEqual(0, f.re(2).groups)

  def test_issue_484(self):
    # Previously, the shim would dereference a null pointer and crash.
    f = re2.Filter()
    with self.assertRaisesRegex(re2.error,
                                r'Match\(\) called before compiling'):
      f.Match('')


if __name__ == '__main__':
  absltest.main()


================================================
FILE: python/setup.py
================================================
# Copyright 2019 The RE2 Authors.  All Rights Reserved.
# Use of this source code is governed by a BSD-style
# license that can be found in the LICENSE file.

import os
import re
import setuptools
import setuptools.command.build_ext
import shutil

long_description = r"""A drop-in replacement for the re module.

It uses RE2 under the hood, of course, so various PCRE features
(e.g. backreferences, look-around assertions) are not supported.
See https://github.com/google/re2/wiki/Syntax for the canonical
reference, but known syntactic "gotchas" relative to Python are:

  * PCRE supports \Z and \z; RE2 supports \z; Python supports \z,
    but calls it \Z. You must rewrite \Z to \z in pattern strings.

Known differences between this module's API and the re module's API:

  * The error class does not provide any error information as attributes.
  * The Options class replaces the re module's flags with RE2's options as
    gettable/settable properties. Please see re2.h for their documentation.
  * The pattern string and the input string do not have to be the same type.
    Any str will be encoded to UTF-8.
  * The pattern string cannot be str if the options specify Latin-1 encoding.

Known issues with regard to building the C++ extension:

  * Building requires RE2 to be installed on your system.
    On Debian, for example, install the libre2-dev package.
  * Building requires pybind11 to be installed on your system OR venv.
    On Debian, for example, install the pybind11-dev package.
    For a venv, install the pybind11 package from PyPI.
  * Building on macOS is known to work, but has been known to fail.
    For example, the system Python may not know which compiler flags
    to set when building bindings for software installed by Homebrew;
    see https://docs.brew.sh/Homebrew-and-Python#brewed-python-modules.
  * Building on Windows has not been tested yet and will probably fail.
"""


class BuildExt(setuptools.command.build_ext.build_ext):

  def build_extension(self, ext):
    if 'GITHUB_ACTIONS' not in os.environ:
      return super().build_extension(ext)

    cmd = ['bazel', 'build']
    try:
      cpu = os.environ['BAZEL_CPU']
      cmd.append(f'--cpu={cpu}')
      cmd.append(f'--platforms=//python:{cpu}')
      if cpu == 'x64_x86_windows':
        # Register the local 32-bit C++ toolchain with highest priority.
        # (This is likely to break in some release of Bazel after 7.0.0,
        # but this special case can hopefully be entirely removed then.)
        cmd.append(f'--extra_toolchains=@local_config_cc//:cc-toolchain-{cpu}')
    except KeyError:
      pass
    try:
      ver = os.environ['MACOSX_DEPLOYMENT_TARGET']
      cmd.append(f'--macos_minimum_os={ver}')
    except KeyError:
      pass
    # Register the local Python toolchains with highest priority.
    cmd.append('--extra_toolchains=//python/toolchains:all')
    cmd += ['--compilation_mode=opt', '--', ':all']
    self.spawn(cmd)

    # This ensures that f'_re2.{importlib.machinery.EXTENSION_SUFFIXES[0]}'
    # is the filename in the destination directory, which is what's needed.
    shutil.copyfile('../bazel-bin/python/_re2.so',
                    self.get_ext_fullpath(ext.name))

    cmd = ['bazel', 'clean', '--expunge']
    self.spawn(cmd)


def options():
  bdist_wheel = {}
  try:
    bdist_wheel['plat_name'] = os.environ['PLAT_NAME']
  except KeyError:
    pass
  return {'bdist_wheel': bdist_wheel}


def include_dirs():
  try:
    import pybind11
    yield pybind11.get_include()
  except ModuleNotFoundError:
    pass


ext_module = setuptools.Extension(
    name='_re2',
    sources=['_re2.cc'],
    include_dirs=list(include_dirs()),
    libraries=['re2'],
    extra_compile_args=['-fvisibility=hidden'],
)

# We need `re2` to be a package, not a module, because it appears that
# modules can't have `.pyi` files, so munge the module into a package.
PACKAGE = 're2'
try:
  # If we are building from the sdist, we are already in package form.
  if not os.path.exists('PKG-INFO'):
    os.makedirs(PACKAGE)
    for filename in (
        're2.py',
        # TODO(junyer): Populate as per https://github.com/google/re2/issues/496.
        # 're2.pyi',
        # '_re2.pyi',
    ):
      with open(filename, 'r') as file:
        contents = file.read()
      filename = re.sub(r'^re2(?=\.py)', '__init__', filename)
      contents = re.sub(r'^(?=import _)', 'from . ', contents, flags=re.MULTILINE)
      with open(f'{PACKAGE}/{filename}', 'x') as file:
        file.write(contents)
    # TODO(junyer): Populate as per https://github.com/google/re2/issues/496.
    # with open(f'{PACKAGE}/py.typed', 'x') as file:
    #   pass

  setuptools.setup(
      name='google-re2',
      version='1.1.20251105',
      description='RE2 Python bindings',
      long_description=long_description,
      long_description_content_type='text/plain',
      author='The RE2 Authors',
      author_email='re2-dev@googlegroups.com',
      url='https://github.com/google/re2',
      packages=[PACKAGE],
      ext_package=PACKAGE,
      ext_modules=[ext_module],
      # Note: Keep the minimum Python version, which appears twice below, in sync with ../.github/workflows/python.yml.
      classifiers=[
          'Development Status :: 5 - Production/Stable',
          'Intended Audience :: Developers',
          'License :: OSI Approved :: BSD License',
          'Programming Language :: C++',
          'Programming Language :: Python :: 3.10',
      ],
      options=options(),
      cmdclass={'build_ext': BuildExt},
      python_requires='~=3.10',
  )
except:
  raise
else:
  # If we are building from the sdist, we are already in package form.
  if not os.path.exists('PKG-INFO'):
    shutil.rmtree(PACKAGE)


================================================
FILE: python/toolchains/generate.py
================================================
# Copyright 2019 The RE2 Authors.  All Rights Reserved.
# Use of this source code is governed by a BSD-style
# license that can be found in the LICENSE file.

import os
import shutil
import sys
import sysconfig


def generate():
  include = sysconfig.get_path('include')
  libs = os.path.join(include, '../libs')

  mydir = os.path.dirname(sys.argv[0]) or '.'
  shutil.copytree(include, f'{mydir}/include')
  try:
    shutil.copytree(libs, f'{mydir}/libs')
  except FileNotFoundError:
    # We must not be running on Windows. :)
    pass

  with open(f'{mydir}/BUILD.bazel', 'x') as file:
    file.write(
        """\
load("@rules_cc//cc:cc_import.bzl", "cc_import")
load("@rules_cc//cc:cc_library.bzl", "cc_library")
load("@rules_python//python/cc:py_cc_toolchain.bzl", "py_cc_toolchain")
load("@rules_python//python:py_runtime.bzl", "py_runtime")
load("@rules_python//python:py_runtime_pair.bzl", "py_runtime_pair")

package(default_visibility = ["//visibility:public"])

toolchain(
    name = "py",
    toolchain = ":py_toolchain",
    toolchain_type = "@rules_python//python:toolchain_type",
)

py_runtime_pair(
    name = "py_toolchain",
    py3_runtime = ":interpreter",
)

py_runtime(
    name = "interpreter",
    interpreter_path = "{interpreter_path}",
    interpreter_version_info = {{
        "major": "{major}",
        "minor": "{minor}",
    }},
    python_version = "PY3",
)

toolchain(
    name = "py_cc",
    toolchain = ":py_cc_toolchain",
    toolchain_type = "@rules_python//python/cc:toolc
Download .txt
gitextract_qg203vwa/

├── .bazelrc
├── .bcr/
│   ├── metadata.template.json
│   ├── presubmit.yml
│   └── source.template.json
├── .github/
│   ├── bazel.sh
│   ├── cmake.sh
│   └── workflows/
│       ├── ci-bazel.yml
│       ├── ci-cmake.yml
│       ├── ci.yml
│       ├── pages.yml
│       ├── python.yml
│       ├── release-bazel.yml
│       └── release.yml
├── .gitignore
├── BUILD.bazel
├── CMakeLists.txt
├── CONTRIBUTING.md
├── LICENSE
├── MODULE.bazel
├── Makefile
├── README.md
├── SECURITY.md
├── WORKSPACE.bazel
├── WORKSPACE.bzlmod
├── app/
│   ├── BUILD.bazel
│   ├── _re2.cc
│   ├── _re2.d.ts
│   ├── app.ts
│   ├── build.sh
│   ├── index.html
│   ├── package.json
│   ├── rollup.config.js
│   └── tsconfig.json
├── benchlog/
│   ├── benchplot.py
│   └── mktable
├── doc/
│   ├── mksyntaxgo
│   ├── mksyntaxhtml
│   ├── mksyntaxwiki
│   ├── syntax.html
│   └── syntax.txt
├── lib/
│   └── git/
│       └── commit-msg.hook
├── libre2.symbols
├── libre2.symbols.darwin
├── python/
│   ├── BUILD.bazel
│   ├── README
│   ├── _re2.cc
│   ├── re2.py
│   ├── re2_test.py
│   ├── setup.py
│   └── toolchains/
│       └── generate.py
├── re2/
│   ├── bitmap256.cc
│   ├── bitmap256.h
│   ├── bitstate.cc
│   ├── compile.cc
│   ├── dfa.cc
│   ├── filtered_re2.cc
│   ├── filtered_re2.h
│   ├── fuzzing/
│   │   └── re2_fuzzer.cc
│   ├── make_perl_groups.pl
│   ├── make_unicode_casefold.py
│   ├── make_unicode_groups.py
│   ├── mimics_pcre.cc
│   ├── nfa.cc
│   ├── onepass.cc
│   ├── parse.cc
│   ├── perl_groups.cc
│   ├── pod_array.h
│   ├── prefilter.cc
│   ├── prefilter.h
│   ├── prefilter_tree.cc
│   ├── prefilter_tree.h
│   ├── prog.cc
│   ├── prog.h
│   ├── re2.cc
│   ├── re2.h
│   ├── regexp.cc
│   ├── regexp.h
│   ├── set.cc
│   ├── set.h
│   ├── simplify.cc
│   ├── sparse_array.h
│   ├── sparse_set.h
│   ├── stringpiece.h
│   ├── testing/
│   │   ├── backtrack.cc
│   │   ├── charclass_test.cc
│   │   ├── compile_test.cc
│   │   ├── dfa_test.cc
│   │   ├── dump.cc
│   │   ├── exhaustive1_test.cc
│   │   ├── exhaustive2_test.cc
│   │   ├── exhaustive3_test.cc
│   │   ├── exhaustive_test.cc
│   │   ├── exhaustive_tester.cc
│   │   ├── exhaustive_tester.h
│   │   ├── filtered_re2_test.cc
│   │   ├── mimics_pcre_test.cc
│   │   ├── null_walker.cc
│   │   ├── parse_test.cc
│   │   ├── possible_match_test.cc
│   │   ├── random_test.cc
│   │   ├── re2_arg_test.cc
│   │   ├── re2_test.cc
│   │   ├── regexp_benchmark.cc
│   │   ├── regexp_generator.cc
│   │   ├── regexp_generator.h
│   │   ├── regexp_test.cc
│   │   ├── required_prefix_test.cc
│   │   ├── search_test.cc
│   │   ├── set_test.cc
│   │   ├── simplify_test.cc
│   │   ├── string_generator.cc
│   │   ├── string_generator.h
│   │   ├── string_generator_test.cc
│   │   ├── tester.cc
│   │   └── tester.h
│   ├── tostring.cc
│   ├── unicode.py
│   ├── unicode_casefold.cc
│   ├── unicode_casefold.h
│   ├── unicode_groups.cc
│   ├── unicode_groups.h
│   └── walker-inl.h
├── re2.pc.in
├── re2Config.cmake.in
├── runtests
├── testinstall.cc
├── ucs2.diff
└── util/
    ├── malloc_counter.h
    ├── pcre.cc
    ├── pcre.h
    ├── rune.cc
    ├── strutil.cc
    ├── strutil.h
    └── utf.h
Download .txt
SYMBOL INDEX (942 symbols across 88 files)

FILE: app/_re2.cc
  type re2_app (line 13) | namespace re2_app {
    type Info (line 15) | struct Info {
    function Info (line 29) | Info GetInfo(const std::string& pattern) {
    function EMSCRIPTEN_BINDINGS (line 77) | EMSCRIPTEN_BINDINGS(_re2) {

FILE: app/_re2.d.ts
  type Info (line 5) | type Info = {
  type MainModule (line 19) | interface MainModule {

FILE: app/app.ts
  class RE2Dev (line 18) | class RE2Dev extends LitElement {
    method constructor (line 22) | constructor() {
    method render (line 43) | override render() {
  type HTMLElementTagNameMap (line 108) | interface HTMLElementTagNameMap {

FILE: benchlog/benchplot.py
  class gnuplot (line 8) | class gnuplot(object):
    method __enter__ (line 27) | def __enter__(self):
    method __exit__ (line 30) | def __exit__(self, type, value, traceback):
    method parse_re2_benchlog (line 38) | def parse_re2_benchlog(self, filename):
    method gen_csv (line 61) | def gen_csv(self):
    method run (line 76) | def run(self):

FILE: python/_re2.cc
  type re2_python (line 30) | namespace re2_python {
    function FromBytes (line 40) | static inline absl::string_view FromBytes(const py::buffer_info& bytes) {
    function OneCharLen (line 46) | static inline int OneCharLen(const char* ptr) {
    function CharLenToBytes (line 52) | ssize_t CharLenToBytes(py::buffer buffer, ssize_t pos, ssize_t len) {
    function BytesToCharLen (line 66) | ssize_t BytesToCharLen(py::buffer buffer, ssize_t pos, ssize_t endpos) {
    function RE2InitShim (line 79) | std::unique_ptr<RE2> RE2InitShim(py::buffer buffer,
    function RE2ErrorShim (line 86) | py::bytes RE2ErrorShim(const RE2& self) {
    function RE2NamedCapturingGroupsShim (line 91) | std::vector<std::pair<py::bytes, int>> RE2NamedCapturingGroupsShim(
    function RE2ProgramFanoutShim (line 102) | std::vector<int> RE2ProgramFanoutShim(const RE2& self) {
    function RE2ReverseProgramFanoutShim (line 108) | std::vector<int> RE2ReverseProgramFanoutShim(const RE2& self) {
    function RE2PossibleMatchRangeShim (line 114) | std::tuple<bool, py::bytes, py::bytes> RE2PossibleMatchRangeShim(
    function RE2MatchShim (line 121) | std::vector<std::pair<ssize_t, ssize_t>> RE2MatchShim(const RE2& self,
    function RE2QuoteMetaShim (line 151) | py::bytes RE2QuoteMetaShim(py::buffer buffer) {
    class Set (line 158) | class Set {
      method Set (line 160) | Set(RE2::Anchor anchor, const RE2::Options& options)
      method Set (line 166) | Set(const Set&) = delete;
      method Set (line 167) | Set& operator=(const Set&) = delete;
      method Add (line 169) | int Add(py::buffer buffer) {
      method Compile (line 176) | bool Compile() {
      method Match (line 181) | std::vector<int> Match(py::buffer buffer) const {
    class Filter (line 194) | class Filter {
      method Filter (line 196) | Filter() = default;
      method Filter (line 200) | Filter(const Filter&) = delete;
      method Filter (line 201) | Filter& operator=(const Filter&) = delete;
      method Add (line 203) | int Add(py::buffer buffer, const RE2::Options& options) {
      method Compile (line 211) | bool Compile() {
      method Match (line 228) | std::vector<int> Match(py::buffer buffer, bool potential) const {
      method RE2 (line 247) | const RE2& GetRE2(int index) const {
    function PYBIND11_MODULE (line 256) | PYBIND11_MODULE(_re2, module) {

FILE: python/re2.py
  class Options (line 41) | class Options(_re2.RE2.Options):
  function compile (line 62) | def compile(pattern, options=None):
  function search (line 73) | def search(pattern, text, options=None):
  function match (line 77) | def match(pattern, text, options=None):
  function fullmatch (line 81) | def fullmatch(pattern, text, options=None):
  function finditer (line 85) | def finditer(pattern, text, options=None):
  function findall (line 89) | def findall(pattern, text, options=None):
  function split (line 93) | def split(pattern, text, maxsplit=0, options=None):
  function subn (line 97) | def subn(pattern, repl, text, count=0, options=None):
  function sub (line 101) | def sub(pattern, repl, text, count=0, options=None):
  function _encode (line 105) | def _encode(t):
  function _decode (line 109) | def _decode(b):
  function escape (line 113) | def escape(pattern):
  function purge (line 124) | def purge():
  class _Regexp (line 132) | class _Regexp(object):
    method _make (line 138) | def _make(cls, pattern, values):
    method __init__ (line 144) | def __init__(self, pattern, options):
    method __getstate__ (line 157) | def __getstate__(self):
    method __setstate__ (line 161) | def __setstate__(self, state):
    method _match (line 168) | def _match(self, anchor, text, pos=None, endpos=None):
    method search (line 236) | def search(self, text, pos=None, endpos=None):
    method match (line 239) | def match(self, text, pos=None, endpos=None):
    method fullmatch (line 242) | def fullmatch(self, text, pos=None, endpos=None):
    method finditer (line 245) | def finditer(self, text, pos=None, endpos=None):
    method findall (line 248) | def findall(self, text, pos=None, endpos=None):
    method _split (line 261) | def _split(self, cb, text, maxsplit=0):
    method split (line 279) | def split(self, text, maxsplit=0):
    method subn (line 284) | def subn(self, repl, text, count=0):
    method sub (line 291) | def sub(self, repl, text, count=0):
    method pattern (line 296) | def pattern(self):
    method options (line 300) | def options(self):
    method groups (line 304) | def groups(self):
    method groupindex (line 308) | def groupindex(self):
    method programsize (line 317) | def programsize(self):
    method reverseprogramsize (line 321) | def reverseprogramsize(self):
    method programfanout (line 325) | def programfanout(self):
    method reverseprogramfanout (line 329) | def reverseprogramfanout(self):
    method possiblematchrange (line 332) | def possiblematchrange(self, maxlen):
  class _Match (line 339) | class _Match(object):
    method __init__ (line 343) | def __init__(self, regexp, text, pos, endpos, spans):
    method _split (line 359) | def _split(cls, template):
    method expand (line 387) | def expand(self, template):
    method __getitem__ (line 411) | def __getitem__(self, group):
    method group (line 424) | def group(self, *groups):
    method groups (line 430) | def groups(self, default=None):
    method groupdict (line 437) | def groupdict(self, default=None):
    method start (line 444) | def start(self, group=0):
    method end (line 449) | def end(self, group=0):
    method span (line 454) | def span(self, group=0):
    method re (line 460) | def re(self):
    method string (line 464) | def string(self):
    method pos (line 468) | def pos(self):
    method endpos (line 472) | def endpos(self):
    method lastindex (line 476) | def lastindex(self):
    method lastgroup (line 490) | def lastgroup(self):
  class Set (line 500) | class Set(object):
    method __init__ (line 505) | def __init__(self, anchor, options=None):
    method SearchSet (line 510) | def SearchSet(cls, options=None):
    method MatchSet (line 514) | def MatchSet(cls, options=None):
    method FullMatchSet (line 518) | def FullMatchSet(cls, options=None):
    method Add (line 521) | def Add(self, pattern):
    method Compile (line 531) | def Compile(self):
    method Match (line 535) | def Match(self, text):
  class Filter (line 544) | class Filter(object):
    method __init__ (line 549) | def __init__(self):
    method Add (line 553) | def Add(self, pattern, options=None):
    method Compile (line 565) | def Compile(self):
    method Match (line 569) | def Match(self, text, potential=False):
    method re (line 577) | def re(self, index):

FILE: python/re2_test.py
  class OptionsTest (line 15) | class OptionsTest(parameterized.TestCase):
    method test_option (line 18) | def test_option(self, name):
  class Re2CompileTest (line 33) | class Re2CompileTest(parameterized.TestCase):
    method test_compile (line 45) | def test_compile(self, pattern, expected_groups, expected_groupindex):
    method test_compile_with_options (line 59) | def test_compile_with_options(self):
    method test_programsize_reverseprogramsize (line 65) | def test_programsize_reverseprogramsize(self):
    method test_programfanout_reverseprogramfanout (line 70) | def test_programfanout_reverseprogramfanout(self):
    method test_possiblematchrange (line 91) | def test_possiblematchrange(self, pattern, maxlen, expected_min_max):
  function upper (line 127) | def upper(match):
  class ReRegexpTest (line 131) | class ReRegexpTest(parameterized.TestCase):
    method test_pickle (line 137) | def test_pickle(self, pattern):
    method test_search (line 144) | def test_search(self, pattern, text, expected_spans):
    method test_search_with_pos_and_endpos (line 152) | def test_search_with_pos_and_endpos(self):
    method test_search_with_bogus_pos_and_endpos (line 169) | def test_search_with_bogus_pos_and_endpos(self):
    method test_match (line 188) | def test_match(self, pattern, text, expected_spans):
    method test_fullmatch (line 198) | def test_fullmatch(self, pattern, text, expected_spans):
    method test_finditer (line 226) | def test_finditer(self, pattern, text, expected_matches):
    method test_findall (line 240) | def test_findall(self, pattern, text, expected_matches):
    method test_split (line 258) | def test_split(self, pattern, text, maxsplit, expected_pieces):
    method test_subn_sub (line 278) | def test_subn_sub(self, pattern, repl, text, count, expected_joined_pi...
  class Re2RegexpTest (line 288) | class Re2RegexpTest(ReRegexpTest):
    method test_compile_with_latin1_encoding (line 293) | def test_compile_with_latin1_encoding(self):
    method test_finditer_with_utf8 (line 308) | def test_finditer_with_utf8(self, pattern, text, expected_matches):
    method test_purge (line 312) | def test_purge(self):
    method test_options (line 318) | def test_options(self):
  class Re2EscapeTest (line 325) | class Re2EscapeTest(parameterized.TestCase):
    method test_escape (line 336) | def test_escape(self, pattern, expected_escaped):
  class ReMatchTest (line 341) | class ReMatchTest(parameterized.TestCase):
    method test_expand (line 346) | def test_expand(self):
    method test_expand_with_octal (line 356) | def test_expand_with_octal(self):
    method test_getitem_group_groups_groupdict (line 374) | def test_getitem_group_groups_groupdict(self):
    method test_bogus_group_start_end_and_span (line 397) | def test_bogus_group_start_end_and_span(self):
    method test_lastindex_lastgroup (line 420) | def test_lastindex_lastgroup(self, pattern, text, expected_lastindex,
  class Re2MatchTest (line 430) | class Re2MatchTest(ReMatchTest):
  class SetTest (line 436) | class SetTest(absltest.TestCase):
    method test_search (line 438) | def test_search(self):
    method test_match (line 447) | def test_match(self):
    method test_fullmatch (line 456) | def test_fullmatch(self):
  class FilterTest (line 466) | class FilterTest(absltest.TestCase):
    method test_match (line 468) | def test_match(self):
    method test_issue_484 (line 486) | def test_issue_484(self):

FILE: python/setup.py
  class BuildExt (line 45) | class BuildExt(setuptools.command.build_ext.build_ext):
    method build_extension (line 47) | def build_extension(self, ext):
  function options (line 82) | def options():
  function include_dirs (line 91) | def include_dirs():

FILE: python/toolchains/generate.py
  function generate (line 11) | def generate():

FILE: re2/bitmap256.cc
  type re2 (line 11) | namespace re2 {

FILE: re2/bitmap256.h
  function Clear (line 27) | void Clear() {

FILE: re2/bitstate.cc
  type re2 (line 34) | namespace re2 {
    type Job (line 36) | struct Job {
    class BitState (line 42) | class BitState {
      method BitState (line 74) | BitState(const BitState&) = delete;
      method BitState (line 75) | BitState& operator=(const BitState&) = delete;

FILE: re2/compile.cc
  type re2 (line 28) | namespace re2 {
    type PatchList (line 41) | struct PatchList {
      method PatchList (line 43) | static PatchList Mk(uint32_t p) {
      method Patch (line 49) | static void Patch(Prog::Inst* inst0, PatchList l, uint32_t p) {
      method PatchList (line 63) | static PatchList Append(Prog::Inst* inst0, PatchList l1, PatchList l...
    type Frag (line 83) | struct Frag {
      method Frag (line 88) | Frag() : begin(0), end(kNullPatchList), nullable(false) {}
      method Frag (line 89) | Frag(uint32_t begin, PatchList end, bool nullable)
    type Encoding (line 94) | enum Encoding {
    class Compiler (line 99) | class Compiler : public Regexp::Walker<Frag> {
      method Compiler (line 223) | Compiler(const Compiler&) = delete;
      method Compiler (line 224) | Compiler& operator=(const Compiler&) = delete;
    function Frag (line 272) | Frag Compiler::NoMatch() {
      method Frag (line 88) | Frag() : begin(0), end(kNullPatchList), nullable(false) {}
      method Frag (line 89) | Frag(uint32_t begin, PatchList end, bool nullable)
    function IsNoMatch (line 277) | static bool IsNoMatch(Frag a) {
    function Frag (line 282) | Frag Compiler::Cat(Frag a, Frag b) {
      method Frag (line 88) | Frag() : begin(0), end(kNullPatchList), nullable(false) {}
      method Frag (line 89) | Frag(uint32_t begin, PatchList end, bool nullable)
    function Frag (line 307) | Frag Compiler::Alt(Frag a, Frag b) {
      method Frag (line 88) | Frag() : begin(0), end(kNullPatchList), nullable(false) {}
      method Frag (line 89) | Frag(uint32_t begin, PatchList end, bool nullable)
    function Frag (line 331) | Frag Compiler::Plus(Frag a, bool nongreedy) {
      method Frag (line 88) | Frag() : begin(0), end(kNullPatchList), nullable(false) {}
      method Frag (line 89) | Frag(uint32_t begin, PatchList end, bool nullable)
    function Frag (line 348) | Frag Compiler::Star(Frag a, bool nongreedy) {
      method Frag (line 88) | Frag() : begin(0), end(kNullPatchList), nullable(false) {}
      method Frag (line 89) | Frag(uint32_t begin, PatchList end, bool nullable)
    function Frag (line 371) | Frag Compiler::Quest(Frag a, bool nongreedy) {
      method Frag (line 88) | Frag() : begin(0), end(kNullPatchList), nullable(false) {}
      method Frag (line 89) | Frag(uint32_t begin, PatchList end, bool nullable)
    function Frag (line 389) | Frag Compiler::ByteRange(int lo, int hi, bool foldcase) {
      method Frag (line 88) | Frag() : begin(0), end(kNullPatchList), nullable(false) {}
      method Frag (line 89) | Frag(uint32_t begin, PatchList end, bool nullable)
    function Frag (line 398) | Frag Compiler::Nop() {
      method Frag (line 88) | Frag() : begin(0), end(kNullPatchList), nullable(false) {}
      method Frag (line 89) | Frag(uint32_t begin, PatchList end, bool nullable)
    function Frag (line 407) | Frag Compiler::Match(int32_t match_id) {
      method Frag (line 88) | Frag() : begin(0), end(kNullPatchList), nullable(false) {}
      method Frag (line 89) | Frag(uint32_t begin, PatchList end, bool nullable)
    function Frag (line 416) | Frag Compiler::EmptyWidth(EmptyOp empty) {
      method Frag (line 88) | Frag() : begin(0), end(kNullPatchList), nullable(false) {}
      method Frag (line 89) | Frag(uint32_t begin, PatchList end, bool nullable)
    function Frag (line 425) | Frag Compiler::Capture(Frag a, int n) {
      method Frag (line 88) | Frag() : begin(0), end(kNullPatchList), nullable(false) {}
      method Frag (line 89) | Frag(uint32_t begin, PatchList end, bool nullable)
    function MaxRune (line 440) | static int MaxRune(int len) {
    function MakeRuneCacheKey (line 474) | static uint64_t MakeRuneCacheKey(uint8_t lo, uint8_t hi, bool foldcase,
    function Frag (line 591) | Frag Compiler::FindByteRange(int root, int id) {
      method Frag (line 88) | Frag() : begin(0), end(kNullPatchList), nullable(false) {}
      method Frag (line 89) | Frag(uint32_t begin, PatchList end, bool nullable)
    function Frag (line 623) | Frag Compiler::EndRange() {
      method Frag (line 88) | Frag() : begin(0), end(kNullPatchList), nullable(false) {}
      method Frag (line 89) | Frag(uint32_t begin, PatchList end, bool nullable)
    function Frag (line 794) | Frag Compiler::Copy(Frag arg) {
      method Frag (line 88) | Frag() : begin(0), end(kNullPatchList), nullable(false) {}
      method Frag (line 89) | Frag(uint32_t begin, PatchList end, bool nullable)
    function Frag (line 803) | Frag Compiler::ShortVisit(Regexp* re, Frag) {
      method Frag (line 88) | Frag() : begin(0), end(kNullPatchList), nullable(false) {}
      method Frag (line 89) | Frag(uint32_t begin, PatchList end, bool nullable)
    function Frag (line 809) | Frag Compiler::PreVisit(Regexp* re, Frag, bool* stop) {
      method Frag (line 88) | Frag() : begin(0), end(kNullPatchList), nullable(false) {}
      method Frag (line 89) | Frag(uint32_t begin, PatchList end, bool nullable)
    function Frag (line 817) | Frag Compiler::Literal(Rune r, bool foldcase) {
      method Frag (line 88) | Frag() : begin(0), end(kNullPatchList), nullable(false) {}
      method Frag (line 89) | Frag(uint32_t begin, PatchList end, bool nullable)
    function Frag (line 840) | Frag Compiler::PostVisit(Regexp* re, Frag, Frag, Frag* child_frags,
      method Frag (line 88) | Frag() : begin(0), end(kNullPatchList), nullable(false) {}
      method Frag (line 89) | Frag(uint32_t begin, PatchList end, bool nullable)
    function IsAnchorStart (line 989) | static bool IsAnchorStart(Regexp** pre, int depth) {
    function IsAnchorEnd (line 1036) | static bool IsAnchorEnd(Regexp** pre, int depth) {
    function Prog (line 1115) | Prog* Compiler::Compile(Regexp* re, bool reversed, int64_t max_mem) {
    function Prog (line 1163) | Prog* Compiler::Finish(Regexp* re) {
    function Prog (line 1206) | Prog* Regexp::CompileToProg(int64_t max_mem) {
    function Prog (line 1210) | Prog* Regexp::CompileToReverseProg(int64_t max_mem) {
    function Frag (line 1214) | Frag Compiler::DotStar() {
      method Frag (line 88) | Frag() : begin(0), end(kNullPatchList), nullable(false) {}
      method Frag (line 89) | Frag(uint32_t begin, PatchList end, bool nullable)
    function Prog (line 1219) | Prog* Compiler::CompileSet(Regexp* re, RE2::Anchor anchor, int64_t max...
    function Prog (line 1261) | Prog* Prog::CompileSet(Regexp* re, RE2::Anchor anchor, int64_t max_mem) {

FILE: re2/dfa.cc
  type re2 (line 59) | namespace re2 {
    class DFA (line 76) | class DFA {
      method ok (line 80) | bool ok() const { return !init_failed_; }
      method kind (line 81) | Prog::MatchKind kind() { return kind_; }
      class RWLocker (line 112) | class RWLocker
      class StateSaver (line 113) | class StateSaver
      class Workq (line 114) | class Workq
      type State (line 119) | struct State {
        method IsMatch (line 120) | inline bool IsMatch() const { return (flag_ & kFlagMatch) != 0; }
        method H (line 123) | H AbslHashValue(H h, const State& a) {
      type StateHash (line 153) | struct StateHash {
      type StateEqual (line 160) | struct StateEqual {
      type SearchParams (line 237) | struct SearchParams {
        method SearchParams (line 238) | SearchParams(absl::string_view text, absl::string_view context,
        method SearchParams (line 265) | SearchParams(const SearchParams&) = delete;
        method SearchParams (line 266) | SearchParams& operator=(const SearchParams&) = delete;
      type StartInfo (line 271) | struct StartInfo {
        method StartInfo (line 272) | StartInfo() : start(NULL) {}
      method ByteMap (line 314) | int ByteMap(int c) {
      method DFA (line 344) | DFA(const DFA&) = delete;
      method DFA (line 345) | DFA& operator=(const DFA&) = delete;
    class DFA::Workq (line 368) | class DFA::Workq : public SparseSet {
      method Workq (line 371) | Workq(int n, int maxmark) :
      method is_mark (line 379) | bool is_mark(int i) { return i >= n_; }
      method maxmark (line 381) | int maxmark() { return maxmark_; }
      method clear (line 383) | void clear() {
      method mark (line 388) | void mark() {
      method size (line 395) | int size() {
      method insert (line 399) | void insert(int id) {
      method insert_new (line 405) | void insert_new(int id) {
      method Workq (line 416) | Workq(const Workq&) = delete;
      method Workq (line 417) | Workq& operator=(const Workq&) = delete;
    class DFA::RWLocker (line 1135) | class DFA::RWLocker {
      method RWLocker (line 1150) | RWLocker(const RWLocker&) = delete;
      method RWLocker (line 1151) | RWLocker& operator=(const RWLocker&) = delete;
    class DFA::StateSaver (line 1219) | class DFA::StateSaver {
      method StateSaver (line 1240) | StateSaver(const StateSaver&) = delete;
      method StateSaver (line 1241) | StateSaver& operator=(const StateSaver&) = delete;
    function DFA (line 1801) | DFA* Prog::GetDFA(MatchKind kind) {
      method ok (line 80) | bool ok() const { return !init_failed_; }
      method kind (line 81) | Prog::MatchKind kind() { return kind_; }
      class RWLocker (line 112) | class RWLocker
      class StateSaver (line 113) | class StateSaver
      class Workq (line 114) | class Workq
      type State (line 119) | struct State {
        method IsMatch (line 120) | inline bool IsMatch() const { return (flag_ & kFlagMatch) != 0; }
        method H (line 123) | H AbslHashValue(H h, const State& a) {
      type StateHash (line 153) | struct StateHash {
      type StateEqual (line 160) | struct StateEqual {
      type SearchParams (line 237) | struct SearchParams {
        method SearchParams (line 238) | SearchParams(absl::string_view text, absl::string_view context,
        method SearchParams (line 265) | SearchParams(const SearchParams&) = delete;
        method SearchParams (line 266) | SearchParams& operator=(const SearchParams&) = delete;
      type StartInfo (line 271) | struct StartInfo {
        method StartInfo (line 272) | StartInfo() : start(NULL) {}
      method ByteMap (line 314) | int ByteMap(int c) {
      method DFA (line 344) | DFA(const DFA&) = delete;
      method DFA (line 345) | DFA& operator=(const DFA&) = delete;

FILE: re2/filtered_re2.cc
  type re2 (line 18) | namespace re2 {
    function FilteredRE2 (line 45) | FilteredRE2& FilteredRE2::operator=(FilteredRE2&& other) {

FILE: re2/filtered_re2.h
  function namespace (line 31) | namespace re2 {

FILE: re2/fuzzing/re2_fuzzer.cc
  class SubexpressionWalker (line 25) | class SubexpressionWalker : public re2::Regexp::Walker<int> {
    method SubexpressionWalker (line 27) | SubexpressionWalker() = default;
    method PostVisit (line 30) | int PostVisit(re2::Regexp* re, int parent_arg, int pre_arg,
    method ShortVisit (line 48) | int ShortVisit(re2::Regexp* re, int parent_arg) override {
    method SubexpressionWalker (line 53) | SubexpressionWalker(const SubexpressionWalker&) = delete;
    method SubexpressionWalker (line 54) | SubexpressionWalker& operator=(const SubexpressionWalker&) = delete;
  class SubstringWalker (line 60) | class SubstringWalker : public re2::Regexp::Walker<int> {
    method SubstringWalker (line 62) | SubstringWalker() = default;
    method PostVisit (line 65) | int PostVisit(re2::Regexp* re, int parent_arg, int pre_arg,
    method ShortVisit (line 91) | int ShortVisit(re2::Regexp* re, int parent_arg) override {
    method SubstringWalker (line 96) | SubstringWalker(const SubstringWalker&) = delete;
    method SubstringWalker (line 97) | SubstringWalker& operator=(const SubstringWalker&) = delete;
  function TestOneInput (line 100) | void TestOneInput(absl::string_view pattern, const RE2::Options& options,
  function LLVMFuzzerTestOneInput (line 241) | int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {

FILE: re2/make_unicode_casefold.py
  function _Delta (line 35) | def _Delta(a, b):
  function _AddDelta (line 50) | def _AddDelta(a, delta):
  function _MakeRanges (line 67) | def _MakeRanges(pairs):
  function main (line 115) | def main():

FILE: re2/make_unicode_groups.py
  function MakeRanges (line 34) | def MakeRanges(codes):
  function PrintRanges (line 46) | def PrintRanges(type, name, ranges):
  function PrintGroup (line 60) | def PrintGroup(name, codes):
  function main (line 98) | def main():

FILE: re2/mimics_pcre.cc
  type re2 (line 29) | namespace re2 {
    class PCREWalker (line 37) | class PCREWalker : public Regexp::Walker<bool> {
      method PCREWalker (line 39) | PCREWalker() {}
      method ShortVisit (line 44) | virtual bool ShortVisit(Regexp* re, bool a) {
      method PCREWalker (line 53) | PCREWalker(const PCREWalker&) = delete;
      method PCREWalker (line 54) | PCREWalker& operator=(const PCREWalker&) = delete;
    class EmptyStringWalker (line 121) | class EmptyStringWalker : public Regexp::Walker<bool> {
      method EmptyStringWalker (line 123) | EmptyStringWalker() {}
      method ShortVisit (line 128) | virtual bool ShortVisit(Regexp* re, bool a) {
      method EmptyStringWalker (line 137) | EmptyStringWalker(const EmptyStringWalker&) = delete;
      method EmptyStringWalker (line 138) | EmptyStringWalker& operator=(const EmptyStringWalker&) = delete;
    function CanBeEmptyString (line 191) | static bool CanBeEmptyString(Regexp* re) {

FILE: re2/nfa.cc
  type re2 (line 45) | namespace re2 {
    class NFA (line 49) | class NFA {
      type Thread (line 69) | struct Thread {
      type AddState (line 78) | struct AddState {
      method CopyCapture (line 112) | void CopyCapture(const char** dst, const char** src) {
      method NFA (line 130) | NFA(const NFA&) = delete;
      method NFA (line 131) | NFA& operator=(const NFA&) = delete;

FILE: re2/onepass.cc
  type re2 (line 76) | namespace re2 {
    type OneState (line 148) | struct OneState {
    function OnePass_Checks (line 186) | void OnePass_Checks() {
    function Satisfy (line 194) | static bool Satisfy(uint32_t cond, absl::string_view context, const ch...
    function ApplyCaptures (line 203) | static void ApplyCaptures(uint32_t cond, const char* p,
    function OneState (line 211) | static inline OneState* IndexToNode(uint8_t* nodes, int statesize,
    function AddQ (line 354) | static bool AddQ(Instq *q, int id) {
    type InstCond (line 363) | struct InstCond {

FILE: re2/parse.cc
  type re2 (line 44) | namespace re2 {
    class Regexp::ParseState (line 70) | class Regexp::ParseState {
      method ParseFlags (line 76) | ParseFlags flags() { return flags_; }
      method rune_max (line 77) | int rune_max() { return rune_max_; }
      method ParseState (line 184) | ParseState(const ParseState&) = delete;
      method ParseState (line 185) | ParseState& operator=(const ParseState&) = delete;
    function Regexp (line 218) | Regexp* Regexp::ParseState::FinishRegexp(Regexp* re) {
    function CaseFold (line 270) | const CaseFold* LookupCaseFold(const CaseFold* f, int n, Rune r) {
    function Rune (line 298) | Rune ApplyFold(const CaseFold* f, Rune r) {
    function Rune (line 333) | Rune CycleFoldRune(Rune r) {
    function AddFoldedRangeLatin1 (line 341) | static void AddFoldedRangeLatin1(CharClassBuilder* cc, Rune lo, Rune h...
    function AddFoldedRange (line 357) | static void AddFoldedRange(CharClassBuilder* cc, Rune lo, Rune hi, int...
    class RepetitionWalker (line 541) | class RepetitionWalker : public Regexp::Walker<int> {
      method RepetitionWalker (line 543) | RepetitionWalker() {}
      method RepetitionWalker (line 550) | RepetitionWalker(const RepetitionWalker&) = delete;
      method RepetitionWalker (line 551) | RepetitionWalker& operator=(const RepetitionWalker&) = delete;
    function Regexp (line 737) | Regexp* Regexp::ParseState::DoFinish() {
    function Regexp (line 752) | Regexp* Regexp::LeadingRegexp(Regexp* re) {
    function Regexp (line 768) | Regexp* Regexp::RemoveLeadingRegexp(Regexp* re) {
    function Rune (line 797) | Rune* Regexp::LeadingString(Regexp* re, int* nrune,
    type Splice (line 900) | struct Splice {
      method Splice (line 901) | Splice(Regexp* prefix, Regexp** sub, int nsub)
    type Frame (line 917) | struct Frame {
      method Frame (line 918) | Frame(Regexp** sub, int nsub)
    class FactorAlternationImpl (line 932) | class FactorAlternationImpl {
    function ParseInteger (line 1359) | static bool ParseInteger(absl::string_view* s, int* np) {
    function MaybeParseRepetition (line 1387) | static bool MaybeParseRepetition(absl::string_view* sp, int* lo, int* ...
    function StringViewToRune (line 1424) | static int StringViewToRune(Rune* r, absl::string_view* sp,
    function IsValidUTF8 (line 1453) | static bool IsValidUTF8(absl::string_view s, RegexpStatus* status) {
    function IsHex (line 1464) | static int IsHex(int c) {
    function UnHex (line 1471) | static int UnHex(int c) {
    function ParseEscape (line 1485) | static bool ParseEscape(absl::string_view* s, Rune* rp,
    function UGroup (line 1661) | static const UGroup* LookupGroup(absl::string_view name,
    function UGroup (line 1671) | static const UGroup* LookupPosixGroup(absl::string_view name) {
    function UGroup (line 1675) | static const UGroup* LookupPerlGroup(absl::string_view name) {
    function UGroup (line 1686) | static const UGroup* LookupUnicodeGroup(absl::string_view name) {
    function AddUGroup (line 1695) | static void AddUGroup(CharClassBuilder* cc, const UGroup* g, int sign,
    function UGroup (line 1746) | const UGroup* MaybeParsePerlCCEscape(absl::string_view* s,
    type ParseStatus (line 1762) | enum ParseStatus {
    function ParseStatus (line 1770) | ParseStatus ParseUnicodeGroup(absl::string_view* s,
    function ParseStatus (line 1860) | static ParseStatus ParseCCName(absl::string_view* s,
    function IsValidCaptureName (line 2054) | static bool IsValidCaptureName(absl::string_view name) {
    function ConvertLatin1ToUTF8 (line 2250) | void ConvertLatin1ToUTF8(absl::string_view latin1, std::string* utf) {
    function Regexp (line 2265) | Regexp* Regexp::Parse(absl::string_view s, ParseFlags global_flags,

FILE: re2/perl_groups.cc
  type re2 (line 6) | namespace re2 {

FILE: re2/pod_array.h
  function namespace (line 11) | namespace re2 {

FILE: re2/prefilter.cc
  type re2 (line 22) | namespace re2 {
    function Prefilter (line 45) | Prefilter* Prefilter::Simplify() {
    function Prefilter (line 74) | Prefilter* Prefilter::AndOr(Op op, Prefilter* a, Prefilter* b) {
    function Prefilter (line 134) | Prefilter* Prefilter::And(Prefilter* a, Prefilter* b) {
    function Prefilter (line 138) | Prefilter* Prefilter::Or(Prefilter* a, Prefilter* b) {
    function Prefilter (line 172) | Prefilter* Prefilter::OrStrings(SSet* ss) {
    function Rune (line 180) | static Rune ToLowerRune(Rune r) {
    function Rune (line 193) | static Rune ToLowerRuneLatin1(Rune r) {
    function Prefilter (line 199) | Prefilter* Prefilter::FromString(const std::string& str) {
    class Prefilter::Info (line 208) | class Prefilter::Info {
      method SSet (line 234) | SSet& exact() { return exact_; }
      method is_exact (line 236) | bool is_exact() const { return is_exact_; }
      class Walker (line 238) | class Walker
    function Prefilter (line 265) | Prefilter* Prefilter::Info::TakeMatch() {
    function RuneToString (line 391) | static std::string RuneToString(Rune r) {
    function RuneToStringLatin1 (line 397) | static std::string RuneToStringLatin1(Rune r) {
    class Prefilter::Info::Walker (line 483) | class Prefilter::Info::Walker : public Regexp::Walker<Prefilter::Info*> {
      method Walker (line 485) | Walker(bool latin1) : latin1_(latin1) {}
      method latin1 (line 496) | bool latin1() { return latin1_; }
      method Walker (line 500) | Walker(const Walker&) = delete;
      method Walker (line 501) | Walker& operator=(const Walker&) = delete;
    function Prefilter (line 646) | Prefilter* Prefilter::FromRegexp(Regexp* re) {
    function Prefilter (line 699) | Prefilter* Prefilter::FromRE2(const RE2* re2) {

FILE: re2/prefilter.h
  function namespace (line 19) | namespace re2 {

FILE: re2/prefilter_tree.cc
  type re2 (line 20) | namespace re2 {
    function Prefilter (line 72) | Prefilter* PrefilterTree::CanonicalNode(NodeSet* nodes, Prefilter* nod...

FILE: re2/prefilter_tree.h
  function namespace (line 28) | namespace re2 {

FILE: re2/prog.cc
  type re2 (line 34) | namespace re2 {
    function AddToQueue (line 142) | static inline void AddToQueue(Workq* q, int id) {
    function ProgToString (line 147) | static std::string ProgToString(Prog* prog, Workq* q) {
    function FlattenedProgToString (line 160) | static std::string FlattenedProgToString(Prog* prog, int start) {
    function IsMatch (line 204) | static bool IsMatch(Prog* prog, Prog::Inst* ip) {
    class ByteMapBuilder (line 343) | class ByteMapBuilder {
      method ByteMapBuilder (line 345) | ByteMapBuilder() {
      method ByteMapBuilder (line 367) | ByteMapBuilder(const ByteMapBuilder&) = delete;
      method ByteMapBuilder (line 368) | ByteMapBuilder& operator=(const ByteMapBuilder&) = delete;
    function FindLSBSet (line 1114) | static int FindLSBSet(uint32_t n) {

FILE: re2/prog.h
  function namespace (line 29) | namespace re2 {

FILE: re2/re2.cc
  type re2 (line 43) | namespace re2 {
    type EmptyStorage (line 80) | struct EmptyStorage {
    function RegexpErrorToRE2 (line 102) | static RE2::ErrorCode RegexpErrorToRE2(re2::RegexpStatusCode code) {
    function trunc (line 138) | static std::string trunc(absl::string_view pattern) {
    function FindMSBSet (line 339) | static int FindMSBSet(uint32_t n) {
    function Fanout (line 360) | static int Fanout(Prog* prog, std::vector<int>* histogram) {
    function ascii_strcasecmp (line 641) | static int ascii_strcasecmp(const char* a, const char* b, size_t len) {
    type re2_internal (line 1067) | namespace re2_internal {
      function Parse (line 1070) | bool Parse(const char* str, size_t n, void* dest) {
      function Parse (line 1076) | bool Parse(const char* str, size_t n, std::string* dest) {
      function Parse (line 1083) | bool Parse(const char* str, size_t n, absl::string_view* dest) {
      function Parse (line 1090) | bool Parse(const char* str, size_t n, char* dest) {
      function Parse (line 1098) | bool Parse(const char* str, size_t n, signed char* dest) {
      function Parse (line 1106) | bool Parse(const char* str, size_t n, unsigned char* dest) {
      function Parse (line 1174) | bool Parse(const char* str, size_t n, float* dest) {
      function Parse (line 1190) | bool Parse(const char* str, size_t n, double* dest) {
      function Parse (line 1206) | bool Parse(const char* str, size_t n, long* dest, int radix) {
      function Parse (line 1221) | bool Parse(const char* str, size_t n, unsigned long* dest, int radix) {
      function Parse (line 1242) | bool Parse(const char* str, size_t n, short* dest, int radix) {
      function Parse (line 1252) | bool Parse(const char* str, size_t n, unsigned short* dest, int radi...
      function Parse (line 1262) | bool Parse(const char* str, size_t n, int* dest, int radix) {
      function Parse (line 1272) | bool Parse(const char* str, size_t n, unsigned int* dest, int radix) {
      function Parse (line 1282) | bool Parse(const char* str, size_t n, long long* dest, int radix) {
      function Parse (line 1297) | bool Parse(const char* str, size_t n, unsigned long long* dest, int ...
    type hooks (line 1318) | namespace hooks {
      function Store (line 1326) | void Store(T* cb) { cb_.store(cb, std::memory_order_release); }
      function T (line 1327) | T* Load() const { return cb_.load(std::memory_order_acquire); }
      function DoNothing (line 1341) | static void DoNothing(const T&) {}

FILE: re2/re2.h
  function namespace (line 229) | namespace re2 {
  function namespace (line 234) | namespace re2 {
  function ProgramSize (line 328) | int ProgramSize() const;
  function FullMatch (line 411) | bool FullMatch(absl::string_view text, const RE2& re, A&&... a) {
  function PartialMatch (line 427) | bool PartialMatch(absl::string_view text, const RE2& re, A&&... a) {
  function Consume (line 445) | bool Consume(absl::string_view* input, const RE2& re, A&&... a) {
  function FindAndConsume (line 463) | bool FindAndConsume(absl::string_view* input, const RE2& re, A&&... a) {
  type Anchor (line 542) | enum Anchor {
  function class (line 618) | class Options {
  function namespace (line 815) | namespace re2_internal {

FILE: re2/regexp.cc
  type re2 (line 29) | namespace re2 {
    type RefStorage (line 80) | struct RefStorage {
    function Regexp (line 103) | Regexp* Regexp::Incref() {
    function Regexp (line 200) | Regexp* Regexp::HaveMatch(int match_id, ParseFlags flags) {
    function Regexp (line 206) | Regexp* Regexp::StarPlusOrQuest(RegexpOp op, Regexp* sub, ParseFlags f...
    function Regexp (line 235) | Regexp* Regexp::Plus(Regexp* sub, ParseFlags flags) {
    function Regexp (line 239) | Regexp* Regexp::Star(Regexp* sub, ParseFlags flags) {
    function Regexp (line 243) | Regexp* Regexp::Quest(Regexp* sub, ParseFlags flags) {
    function Regexp (line 247) | Regexp* Regexp::ConcatOrAlternate(RegexpOp op, Regexp** sub, int nsub,
    function Regexp (line 295) | Regexp* Regexp::Concat(Regexp** sub, int nsub, ParseFlags flags) {
    function Regexp (line 299) | Regexp* Regexp::Alternate(Regexp** sub, int nsub, ParseFlags flags) {
    function Regexp (line 303) | Regexp* Regexp::AlternateNoFactor(Regexp** sub, int nsub, ParseFlags f...
    function Regexp (line 307) | Regexp* Regexp::Capture(Regexp* sub, ParseFlags flags, int cap) {
    function Regexp (line 315) | Regexp* Regexp::Repeat(Regexp* sub, ParseFlags flags, int min, int max) {
    function Regexp (line 324) | Regexp* Regexp::NewLiteral(Rune rune, ParseFlags flags) {
    function Regexp (line 330) | Regexp* Regexp::LiteralString(Rune* runes, int nrunes, ParseFlags flag...
    function Regexp (line 341) | Regexp* Regexp::NewCharClass(CharClass* cc, ParseFlags flags) {
    function TopEqual (line 359) | static bool TopEqual(Regexp* a, Regexp* b) {
    type RegexpStatusCode (line 529) | enum RegexpStatusCode
    class NumCapturesWalker (line 553) | class NumCapturesWalker : public Regexp::Walker<Ignored> {
      method NumCapturesWalker (line 555) | NumCapturesWalker() : ncapture_(0) {}
      method ncapture (line 556) | int ncapture() { return ncapture_; }
      method Ignored (line 558) | virtual Ignored PreVisit(Regexp* re, Ignored ignored, bool* stop) {
      method Ignored (line 564) | virtual Ignored ShortVisit(Regexp* re, Ignored ignored) {
      method NumCapturesWalker (line 575) | NumCapturesWalker(const NumCapturesWalker&) = delete;
      method NumCapturesWalker (line 576) | NumCapturesWalker& operator=(const NumCapturesWalker&) = delete;
    class NamedCapturesWalker (line 586) | class NamedCapturesWalker : public Regexp::Walker<Ignored> {
      method NamedCapturesWalker (line 588) | NamedCapturesWalker() : map_(NULL) {}
      method Ignored (line 597) | virtual Ignored PreVisit(Regexp* re, Ignored ignored, bool* stop) {
      method Ignored (line 611) | virtual Ignored ShortVisit(Regexp* re, Ignored ignored) {
      method NamedCapturesWalker (line 622) | NamedCapturesWalker(const NamedCapturesWalker&) = delete;
      method NamedCapturesWalker (line 623) | NamedCapturesWalker& operator=(const NamedCapturesWalker&) = delete;
    class CaptureNamesWalker (line 633) | class CaptureNamesWalker : public Regexp::Walker<Ignored> {
      method CaptureNamesWalker (line 635) | CaptureNamesWalker() : map_(NULL) {}
      method Ignored (line 644) | virtual Ignored PreVisit(Regexp* re, Ignored ignored, bool* stop) {
      method Ignored (line 655) | virtual Ignored ShortVisit(Regexp* re, Ignored ignored) {
      method CaptureNamesWalker (line 666) | CaptureNamesWalker(const CaptureNamesWalker&) = delete;
      method CaptureNamesWalker (line 667) | CaptureNamesWalker& operator=(const CaptureNamesWalker&) = delete;
    function ConvertRunesToBytes (line 676) | void ConvertRunesToBytes(bool latin1, Rune* runes, int nrunes,
    function CharClassBuilder (line 855) | CharClassBuilder* CharClassBuilder::Copy() {
    function CharClass (line 939) | CharClass* CharClass::New(size_t maxranges) {
    function CharClass (line 955) | CharClass* CharClass::Negate() {
    function CharClass (line 992) | CharClass* CharClassBuilder::GetCharClass() {

FILE: re2/regexp.h
  function namespace (line 101) | namespace re2 {
  function class (line 277) | class Regexp {
  type std (line 631) | typedef std::set<RuneRange, RuneRangeLess> RuneRangeSet;
  function class (line 633) | class CharClassBuilder {
  function Regexp (line 685) | inline Regexp::ParseFlags operator~(Regexp::ParseFlags a) {

FILE: re2/set.cc
  type re2 (line 23) | namespace re2 {

FILE: re2/set.h
  function namespace (line 16) | namespace re2 {
  function namespace (line 21) | namespace re2 {

FILE: re2/simplify.cc
  type re2 (line 21) | namespace re2 {
    class CoalesceWalker (line 109) | class CoalesceWalker : public Regexp::Walker<Regexp*> {
      method CoalesceWalker (line 111) | CoalesceWalker() {}
      method CoalesceWalker (line 131) | CoalesceWalker(const CoalesceWalker&) = delete;
      method CoalesceWalker (line 132) | CoalesceWalker& operator=(const CoalesceWalker&) = delete;
    class SimplifyWalker (line 139) | class SimplifyWalker : public Regexp::Walker<Regexp*> {
      method SimplifyWalker (line 141) | SimplifyWalker() {}
      method SimplifyWalker (line 167) | SimplifyWalker(const SimplifyWalker&) = delete;
      method SimplifyWalker (line 168) | SimplifyWalker& operator=(const SimplifyWalker&) = delete;
    function Regexp (line 180) | Regexp* Regexp::Simplify() {
    function ChildArgsChanged (line 207) | static bool ChildArgsChanged(Regexp* re, Regexp** child_args) {
    function Regexp (line 221) | Regexp* CoalesceWalker::Copy(Regexp* re) {
    function Regexp (line 225) | Regexp* CoalesceWalker::ShortVisit(Regexp* re, Regexp* parent_arg) {
    function Regexp (line 233) | Regexp* CoalesceWalker::PostVisit(Regexp* re,
    function Regexp (line 447) | Regexp* SimplifyWalker::Copy(Regexp* re) {
    function Regexp (line 451) | Regexp* SimplifyWalker::ShortVisit(Regexp* re, Regexp* parent_arg) {
    function Regexp (line 459) | Regexp* SimplifyWalker::PreVisit(Regexp* re, Regexp* parent_arg, bool*...
    function Regexp (line 467) | Regexp* SimplifyWalker::PostVisit(Regexp* re,
    function Regexp (line 576) | Regexp* SimplifyWalker::Concat2(Regexp* re1, Regexp* re2,
    function IsEmptyOp (line 587) | static bool IsEmptyOp(Regexp* re) {
    function Regexp (line 602) | Regexp* SimplifyWalker::SimplifyRepeat(Regexp* re, int min, int max,
    function Regexp (line 677) | Regexp* SimplifyWalker::SimplifyCharClass(Regexp* re) {

FILE: re2/sparse_array.h
  function namespace (line 109) | namespace re2 {

FILE: re2/sparse_set.h
  function namespace (line 68) | namespace re2 {
  type SparseSetT (line 262) | typedef SparseSetT<void> SparseSet;

FILE: re2/stringpiece.h
  function namespace (line 10) | namespace re2 {

FILE: re2/testing/backtrack.cc
  type re2 (line 38) | namespace re2 {
    class Backtracker (line 56) | class Backtracker {
      method Backtracker (line 86) | Backtracker(const Backtracker&) = delete;
      method Backtracker (line 87) | Backtracker& operator=(const Backtracker&) = delete;

FILE: re2/testing/charclass_test.cc
  type re2 (line 15) | namespace re2 {
    type CCTest (line 17) | struct CCTest {
    function Broke (line 91) | static void Broke(const char *desc, const CCTest* t, CharClass* cc) {
    function ShouldContain (line 114) | bool ShouldContain(CCTest *t, int x) {
    function CharClass (line 123) | CharClass* Negate(CharClass *cc) {
    function Delete (line 127) | void Delete(CharClass* cc) {
    function CharClassBuilder (line 131) | CharClassBuilder* Negate(CharClassBuilder* cc) {
    function Delete (line 137) | void Delete(CharClassBuilder* cc) {
    function CorrectCC (line 142) | bool CorrectCC(CharClass *cc, CCTest *t, const char *desc) {
    function TEST (line 200) | TEST(TestCharClassBuilder, Adds) {

FILE: re2/testing/compile_test.cc
  type re2 (line 18) | namespace re2 {
    type Test (line 26) | struct Test {
    function TEST (line 132) | TEST(TestRegexpCompileToProg, Simple) {
    function DumpByteMap (line 163) | static void DumpByteMap(absl::string_view pattern, Regexp::ParseFlags ...
    function TEST (line 185) | TEST(TestCompile, Latin1Ranges) {
    function TEST (line 197) | TEST(TestCompile, OtherByteMapTests) {
    function TEST (line 232) | TEST(TestCompile, UTF8Ranges) {
    function TEST (line 252) | TEST(TestCompile, InsufficientMemory) {
    function Dump (line 264) | static void Dump(absl::string_view pattern, Regexp::ParseFlags flags,
    function TEST (line 286) | TEST(TestCompile, Bug26705922) {
    function TEST (line 343) | TEST(TestCompile, Bug35237384) {

FILE: re2/testing/dfa_test.cc
  function ABSL_FLAG (line 27) | ABSL_FLAG(int, repeat, 2, "Repetition count.");

FILE: re2/testing/dump.cc
  type re2 (line 29) | namespace re2 {
    function DumpRegexpAppending (line 58) | static void DumpRegexpAppending(Regexp* re, std::string* s) {

FILE: re2/testing/exhaustive1_test.cc
  type re2 (line 14) | namespace re2 {
    function TEST (line 17) | TEST(Repetition, Simple) {
    function TEST (line 29) | TEST(Repetition, Capturing) {

FILE: re2/testing/exhaustive2_test.cc
  type re2 (line 16) | namespace re2 {
    function TEST (line 19) | TEST(EmptyString, Exhaustive) {
    function TEST (line 26) | TEST(Punctuation, Literals) {
    function TEST (line 38) | TEST(LineEnds, Exhaustive) {

FILE: re2/testing/exhaustive3_test.cc
  type re2 (line 17) | namespace re2 {
    function TEST (line 20) | TEST(CharacterClasses, Exhaustive) {
    function TEST (line 28) | TEST(CharacterClasses, ExhaustiveAB) {
    function UTF8 (line 36) | static std::string UTF8(Rune r) {
    function TEST (line 73) | TEST(InterestingUTF8, SingleOps) {
    function TEST (line 86) | TEST(InterestingUTF8, AB) {

FILE: re2/testing/exhaustive_test.cc
  type re2 (line 10) | namespace re2 {
    function TEST (line 13) | TEST(EgrepLiterals, Lowercase) {
    function TEST (line 18) | TEST(EgrepLiterals, MixedCase) {
    function TEST (line 23) | TEST(EgrepLiterals, FoldCase) {
    function TEST (line 31) | TEST(EgrepLiterals, UTF8) {

FILE: re2/testing/exhaustive_tester.cc
  type re2 (line 44) | namespace re2 {
    function PrintResult (line 68) | static void PrintResult(const RE2& re, absl::string_view input,
    function ExhaustiveTest (line 160) | void ExhaustiveTest(int maxatoms, int maxops,
    function EgrepTest (line 188) | void EgrepTest(int maxatoms, int maxops, const std::string& alphabet,

FILE: re2/testing/exhaustive_tester.h
  function namespace (line 16) | namespace re2 {

FILE: re2/testing/filtered_re2_test.cc
  type re2 (line 19) | namespace re2 {
    type FilterTestVars (line 21) | struct FilterTestVars {
      method FilterTestVars (line 22) | FilterTestVars() {}
      method FilterTestVars (line 23) | explicit FilterTestVars(int min_atom_len) : f(min_atom_len) {}
    function TEST (line 32) | TEST(FilteredRE2Test, EmptyTest) {
    function TEST (line 46) | TEST(FilteredRE2Test, SmallOrTest) {
    function TEST (line 59) | TEST(FilteredRE2Test, SmallLatinTest) {
    type AtomTest (line 75) | struct AtomTest {
    function AddRegexpsAndCompile (line 150) | void AddRegexpsAndCompile(const char* regexps[],
    function CheckExpectedAtoms (line 160) | bool CheckExpectedAtoms(const char* atoms[],
    function TEST (line 188) | TEST(FilteredRE2Test, AtomTests) {
    function FindAtomIndices (line 207) | void FindAtomIndices(const std::vector<std::string>& atoms,
    function TEST (line 221) | TEST(FilteredRE2Test, MatchEmptyPattern) {
    function TEST (line 239) | TEST(FilteredRE2Test, MatchTests) {
    function TEST (line 284) | TEST(FilteredRE2Test, EmptyStringInStringSetBug) {
    function TEST (line 298) | TEST(FilteredRE2Test, MoveSemantics) {

FILE: re2/testing/mimics_pcre_test.cc
  type re2 (line 12) | namespace re2 {
    type PCRETest (line 14) | struct PCRETest {
    function TEST (line 62) | TEST(MimicsPCRE, SimpleTests) {

FILE: re2/testing/null_walker.cc
  type re2 (line 9) | namespace re2 {
    class NullWalker (line 13) | class NullWalker : public Regexp::Walker<bool> {
      method NullWalker (line 15) | NullWalker() {}
      method ShortVisit (line 20) | virtual bool ShortVisit(Regexp* re, bool a) {
      method NullWalker (line 29) | NullWalker(const NullWalker&) = delete;
      method NullWalker (line 30) | NullWalker& operator=(const NullWalker&) = delete;

FILE: re2/testing/parse_test.cc
  type re2 (line 16) | namespace re2 {
    type Test (line 23) | struct Test {
    function RegexpEqualTestingOnly (line 255) | bool RegexpEqualTestingOnly(Regexp* a, Regexp* b) {
    function TestParse (line 259) | void TestParse(const Test* tests, int ntests, Regexp::ParseFlags flags,
    function TEST (line 292) | TEST(TestParse, SimpleRegexps) {
    function TEST (line 309) | TEST(TestParse, FoldCase) {
    function TEST (line 318) | TEST(TestParse, Literal) {
    function TEST (line 331) | TEST(TestParse, MatchNL) {
    function TEST (line 343) | TEST(TestParse, NoMatchNL) {
    function TEST (line 394) | TEST(TestParse, Prefix) {
    function TEST (line 410) | TEST(TestParse, Nested) {
    function TEST (line 471) | TEST(TestParse, InvalidRegexps) {
    function TEST (line 495) | TEST(TestToString, EquivalentParse) {
    function TEST (line 535) | TEST(NamedCaptures, ErrorArgs) {
    function TEST (line 561) | TEST(LookAround, ErrorArgs) {

FILE: re2/testing/possible_match_test.cc
  type re2 (line 22) | namespace re2 {
    function TEST (line 26) | TEST(CplusplusStrings, EightBit) {
    type PrefixTest (line 32) | struct PrefixTest {
    function TEST (line 112) | TEST(PossibleMatchRange, HandWritten) {
    function TEST (line 137) | TEST(PossibleMatchRange, Failures) {
    class PossibleMatchTester (line 174) | class PossibleMatchTester : public RegexpGenerator {
      method PossibleMatchTester (line 176) | PossibleMatchTester(int maxatoms,
      method regexps (line 186) | int regexps()  { return regexps_; }
      method tests (line 187) | int tests()    { return tests_; }
      method PossibleMatchTester (line 198) | PossibleMatchTester(const PossibleMatchTester&) = delete;
      method PossibleMatchTester (line 199) | PossibleMatchTester& operator=(const PossibleMatchTester&) = delete;
    function TEST (line 234) | TEST(PossibleMatchRange, Exhaustive) {

FILE: re2/testing/random_test.cc
  type re2 (line 21) | namespace re2 {
    function RandomTest (line 26) | static void RandomTest(int maxatoms, int maxops,
    function TEST (line 52) | TEST(Random, SmallEgrepLiterals) {
    function TEST (line 59) | TEST(Random, BigEgrepLiterals) {
    function TEST (line 67) | TEST(Random, SmallEgrepCaptures) {
    function TEST (line 75) | TEST(Random, BigEgrepCaptures) {
    function TEST (line 85) | TEST(Random, Complicated) {

FILE: re2/testing/re2_arg_test.cc
  type SuccessTable (line 21) | struct SuccessTable {
  function ParseFrom (line 140) | bool ParseFrom(const char* str, size_t n) {
  function ParseFrom (line 149) | bool ParseFrom(const char* str, size_t n) {
  function ParseFrom (line 154) | void ParseFrom(const char* str) {}

FILE: re2/testing/re2_test.cc
  type re2 (line 32) | namespace re2 {
    function TEST (line 34) | TEST(RE2, HexTests) {
    function TEST (line 58) | TEST(RE2, OctalTests) {

FILE: re2/testing/regexp_benchmark.cc
  type re2 (line 28) | namespace re2 {
    function Test (line 37) | void Test() {
    function MemoryUsage (line 57) | void MemoryUsage() {
    function NumCPUs (line 126) | int NumCPUs() {
    function RandomText (line 161) | std::string RandomText(int64_t nbytes) {
    function Search (line 182) | void Search(benchmark::State& state, const char* regexp, SearchImpl* s...
    function Search_Easy0_CachedDFA (line 212) | void Search_Easy0_CachedDFA(benchmark::State& state)     { Search(stat...
    function Search_Easy0_CachedNFA (line 213) | void Search_Easy0_CachedNFA(benchmark::State& state)     { Search(stat...
    function Search_Easy0_CachedPCRE (line 214) | void Search_Easy0_CachedPCRE(benchmark::State& state)    { Search(stat...
    function Search_Easy0_CachedRE2 (line 215) | void Search_Easy0_CachedRE2(benchmark::State& state)     { Search(stat...
    function Search_Easy1_CachedDFA (line 224) | void Search_Easy1_CachedDFA(benchmark::State& state)     { Search(stat...
    function Search_Easy1_CachedNFA (line 225) | void Search_Easy1_CachedNFA(benchmark::State& state)     { Search(stat...
    function Search_Easy1_CachedPCRE (line 226) | void Search_Easy1_CachedPCRE(benchmark::State& state)    { Search(stat...
    function Search_Easy1_CachedRE2 (line 227) | void Search_Easy1_CachedRE2(benchmark::State& state)     { Search(stat...
    function Search_Easy2_CachedDFA (line 236) | void Search_Easy2_CachedDFA(benchmark::State& state)     { Search(stat...
    function Search_Easy2_CachedNFA (line 237) | void Search_Easy2_CachedNFA(benchmark::State& state)     { Search(stat...
    function Search_Easy2_CachedPCRE (line 238) | void Search_Easy2_CachedPCRE(benchmark::State& state)    { Search(stat...
    function Search_Easy2_CachedRE2 (line 239) | void Search_Easy2_CachedRE2(benchmark::State& state)     { Search(stat...
    function Search_Medium_CachedDFA (line 248) | void Search_Medium_CachedDFA(benchmark::State& state)     { Search(sta...
    function Search_Medium_CachedNFA (line 249) | void Search_Medium_CachedNFA(benchmark::State& state)     { Search(sta...
    function Search_Medium_CachedPCRE (line 250) | void Search_Medium_CachedPCRE(benchmark::State& state)    { Search(sta...
    function Search_Medium_CachedRE2 (line 251) | void Search_Medium_CachedRE2(benchmark::State& state)     { Search(sta...
    function Search_Hard_CachedDFA (line 260) | void Search_Hard_CachedDFA(benchmark::State& state)     { Search(state...
    function Search_Hard_CachedNFA (line 261) | void Search_Hard_CachedNFA(benchmark::State& state)     { Search(state...
    function Search_Hard_CachedPCRE (line 262) | void Search_Hard_CachedPCRE(benchmark::State& state)    { Search(state...
    function Search_Hard_CachedRE2 (line 263) | void Search_Hard_CachedRE2(benchmark::State& state)     { Search(state...
    function Search_Fanout_CachedDFA (line 272) | void Search_Fanout_CachedDFA(benchmark::State& state)     { Search(sta...
    function Search_Fanout_CachedNFA (line 273) | void Search_Fanout_CachedNFA(benchmark::State& state)     { Search(sta...
    function Search_Fanout_CachedPCRE (line 274) | void Search_Fanout_CachedPCRE(benchmark::State& state)    { Search(sta...
    function Search_Fanout_CachedRE2 (line 275) | void Search_Fanout_CachedRE2(benchmark::State& state)     { Search(sta...
    function Search_Parens_CachedDFA (line 284) | void Search_Parens_CachedDFA(benchmark::State& state)     { Search(sta...
    function Search_Parens_CachedNFA (line 285) | void Search_Parens_CachedNFA(benchmark::State& state)     { Search(sta...
    function Search_Parens_CachedPCRE (line 286) | void Search_Parens_CachedPCRE(benchmark::State& state)    { Search(sta...
    function Search_Parens_CachedRE2 (line 287) | void Search_Parens_CachedRE2(benchmark::State& state)     { Search(sta...
    function SearchBigFixed (line 296) | void SearchBigFixed(benchmark::State& state, SearchImpl* search) {
    function Search_BigFixed_CachedDFA (line 306) | void Search_BigFixed_CachedDFA(benchmark::State& state)     { SearchBi...
    function Search_BigFixed_CachedNFA (line 307) | void Search_BigFixed_CachedNFA(benchmark::State& state)     { SearchBi...
    function Search_BigFixed_CachedPCRE (line 308) | void Search_BigFixed_CachedPCRE(benchmark::State& state)    { SearchBi...
    function Search_BigFixed_CachedRE2 (line 309) | void Search_BigFixed_CachedRE2(benchmark::State& state)     { SearchBi...
    function FindAndConsume (line 320) | void FindAndConsume(benchmark::State& state) {
    function SearchSuccess (line 337) | void SearchSuccess(benchmark::State& state, const char* regexp,
    function Search_Success_DFA (line 346) | void Search_Success_DFA(benchmark::State& state)     { SearchSuccess(s...
    function Search_Success_NFA (line 347) | void Search_Success_NFA(benchmark::State& state)     { SearchSuccess(s...
    function Search_Success_PCRE (line 348) | void Search_Success_PCRE(benchmark::State& state)    { SearchSuccess(s...
    function Search_Success_RE2 (line 349) | void Search_Success_RE2(benchmark::State& state)     { SearchSuccess(s...
    function Search_Success_OnePass (line 350) | void Search_Success_OnePass(benchmark::State& state) { SearchSuccess(s...
    function Search_Success_CachedDFA (line 360) | void Search_Success_CachedDFA(benchmark::State& state)     { SearchSuc...
    function Search_Success_CachedNFA (line 361) | void Search_Success_CachedNFA(benchmark::State& state)     { SearchSuc...
    function Search_Success_CachedPCRE (line 362) | void Search_Success_CachedPCRE(benchmark::State& state)    { SearchSuc...
    function Search_Success_CachedRE2 (line 363) | void Search_Success_CachedRE2(benchmark::State& state)     { SearchSuc...
    function Search_Success_CachedOnePass (line 364) | void Search_Success_CachedOnePass(benchmark::State& state) { SearchSuc...
    function Search_Success1_DFA (line 377) | void Search_Success1_DFA(benchmark::State& state)      { SearchSuccess...
    function Search_Success1_NFA (line 378) | void Search_Success1_NFA(benchmark::State& state)      { SearchSuccess...
    function Search_Success1_PCRE (line 379) | void Search_Success1_PCRE(benchmark::State& state)     { SearchSuccess...
    function Search_Success1_RE2 (line 380) | void Search_Success1_RE2(benchmark::State& state)      { SearchSuccess...
    function Search_Success1_BitState (line 381) | void Search_Success1_BitState(benchmark::State& state) { SearchSuccess...
    function Search_Success1_CachedDFA (line 391) | void Search_Success1_CachedDFA(benchmark::State& state)      { SearchS...
    function Search_Success1_CachedNFA (line 392) | void Search_Success1_CachedNFA(benchmark::State& state)      { SearchS...
    function Search_Success1_CachedPCRE (line 393) | void Search_Success1_CachedPCRE(benchmark::State& state)     { SearchS...
    function Search_Success1_CachedRE2 (line 394) | void Search_Success1_CachedRE2(benchmark::State& state)      { SearchS...
    function Search_Success1_CachedBitState (line 395) | void Search_Success1_CachedBitState(benchmark::State& state) { SearchS...
    function SearchAltMatch (line 408) | void SearchAltMatch(benchmark::State& state, SearchImpl* search) {
    function Search_AltMatch_DFA (line 414) | void Search_AltMatch_DFA(benchmark::State& state)      { SearchAltMatc...
    function Search_AltMatch_NFA (line 415) | void Search_AltMatch_NFA(benchmark::State& state)      { SearchAltMatc...
    function Search_AltMatch_OnePass (line 416) | void Search_AltMatch_OnePass(benchmark::State& state)  { SearchAltMatc...
    function Search_AltMatch_BitState (line 417) | void Search_AltMatch_BitState(benchmark::State& state) { SearchAltMatc...
    function Search_AltMatch_PCRE (line 418) | void Search_AltMatch_PCRE(benchmark::State& state)     { SearchAltMatc...
    function Search_AltMatch_RE2 (line 419) | void Search_AltMatch_RE2(benchmark::State& state)      { SearchAltMatc...
    function Search_AltMatch_CachedDFA (line 430) | void Search_AltMatch_CachedDFA(benchmark::State& state)      { SearchA...
    function Search_AltMatch_CachedNFA (line 431) | void Search_AltMatch_CachedNFA(benchmark::State& state)      { SearchA...
    function Search_AltMatch_CachedOnePass (line 432) | void Search_AltMatch_CachedOnePass(benchmark::State& state)  { SearchA...
    function Search_AltMatch_CachedBitState (line 433) | void Search_AltMatch_CachedBitState(benchmark::State& state) { SearchA...
    function Search_AltMatch_CachedPCRE (line 434) | void Search_AltMatch_CachedPCRE(benchmark::State& state)     { SearchA...
    function Search_AltMatch_CachedRE2 (line 435) | void Search_AltMatch_CachedRE2(benchmark::State& state)      { SearchA...
    function SearchDigits (line 448) | void SearchDigits(benchmark::State& state, SearchImpl* search) {
    function Search_Digits_DFA (line 454) | void Search_Digits_DFA(benchmark::State& state)         { SearchDigits...
    function Search_Digits_NFA (line 455) | void Search_Digits_NFA(benchmark::State& state)         { SearchDigits...
    function Search_Digits_OnePass (line 456) | void Search_Digits_OnePass(benchmark::State& state)     { SearchDigits...
    function Search_Digits_PCRE (line 457) | void Search_Digits_PCRE(benchmark::State& state)        { SearchDigits...
    function Search_Digits_RE2 (line 458) | void Search_Digits_RE2(benchmark::State& state)         { SearchDigits...
    function Search_Digits_BitState (line 459) | void Search_Digits_BitState(benchmark::State& state)    { SearchDigits...
    function Parse3Digits (line 472) | void Parse3Digits(benchmark::State& state,
    function Parse_Digits_NFA (line 479) | void Parse_Digits_NFA(benchmark::State& state)         { Parse3Digits(...
    function Parse_Digits_OnePass (line 480) | void Parse_Digits_OnePass(benchmark::State& state)     { Parse3Digits(...
    function Parse_Digits_PCRE (line 481) | void Parse_Digits_PCRE(benchmark::State& state)        { Parse3Digits(...
    function Parse_Digits_RE2 (line 482) | void Parse_Digits_RE2(benchmark::State& state)         { Parse3Digits(...
    function Parse_Digits_Backtrack (line 483) | void Parse_Digits_Backtrack(benchmark::State& state)   { Parse3Digits(...
    function Parse_Digits_BitState (line 484) | void Parse_Digits_BitState(benchmark::State& state)    { Parse3Digits(...
    function Parse_CachedDigits_NFA (line 495) | void Parse_CachedDigits_NFA(benchmark::State& state)         { Parse3D...
    function Parse_CachedDigits_OnePass (line 496) | void Parse_CachedDigits_OnePass(benchmark::State& state)     { Parse3D...
    function Parse_CachedDigits_PCRE (line 497) | void Parse_CachedDigits_PCRE(benchmark::State& state)        { Parse3D...
    function Parse_CachedDigits_RE2 (line 498) | void Parse_CachedDigits_RE2(benchmark::State& state)         { Parse3D...
    function Parse_CachedDigits_Backtrack (line 499) | void Parse_CachedDigits_Backtrack(benchmark::State& state)   { Parse3D...
    function Parse_CachedDigits_BitState (line 500) | void Parse_CachedDigits_BitState(benchmark::State& state)    { Parse3D...
    function Parse3DigitDs (line 511) | void Parse3DigitDs(benchmark::State& state,
    function Parse_DigitDs_NFA (line 518) | void Parse_DigitDs_NFA(benchmark::State& state)         { Parse3DigitD...
    function Parse_DigitDs_OnePass (line 519) | void Parse_DigitDs_OnePass(benchmark::State& state)     { Parse3DigitD...
    function Parse_DigitDs_PCRE (line 520) | void Parse_DigitDs_PCRE(benchmark::State& state)        { Parse3DigitD...
    function Parse_DigitDs_RE2 (line 521) | void Parse_DigitDs_RE2(benchmark::State& state)         { Parse3DigitD...
    function Parse_DigitDs_Backtrack (line 522) | void Parse_DigitDs_Backtrack(benchmark::State& state)   { Parse3DigitD...
    function Parse_DigitDs_BitState (line 523) | void Parse_DigitDs_BitState(benchmark::State& state)    { Parse3DigitD...
    function Parse_CachedDigitDs_NFA (line 534) | void Parse_CachedDigitDs_NFA(benchmark::State& state)         { Parse3...
    function Parse_CachedDigitDs_OnePass (line 535) | void Parse_CachedDigitDs_OnePass(benchmark::State& state)     { Parse3...
    function Parse_CachedDigitDs_PCRE (line 536) | void Parse_CachedDigitDs_PCRE(benchmark::State& state)        { Parse3...
    function Parse_CachedDigitDs_RE2 (line 537) | void Parse_CachedDigitDs_RE2(benchmark::State& state)         { Parse3...
    function Parse_CachedDigitDs_Backtrack (line 538) | void Parse_CachedDigitDs_Backtrack(benchmark::State& state)   { Parse3...
    function Parse_CachedDigitDs_BitState (line 539) | void Parse_CachedDigitDs_BitState(benchmark::State& state)    { Parse3...
    function Parse1Split (line 552) | void Parse1Split(benchmark::State& state,
    function Parse_Split_NFA (line 559) | void Parse_Split_NFA(benchmark::State& state)         { Parse1Split(st...
    function Parse_Split_OnePass (line 560) | void Parse_Split_OnePass(benchmark::State& state)     { Parse1Split(st...
    function Parse_Split_PCRE (line 561) | void Parse_Split_PCRE(benchmark::State& state)        { Parse1Split(st...
    function Parse_Split_RE2 (line 562) | void Parse_Split_RE2(benchmark::State& state)         { Parse1Split(st...
    function Parse_Split_BitState (line 563) | void Parse_Split_BitState(benchmark::State& state)    { Parse1Split(st...
    function Parse_CachedSplit_NFA (line 573) | void Parse_CachedSplit_NFA(benchmark::State& state)         { Parse1Sp...
    function Parse_CachedSplit_OnePass (line 574) | void Parse_CachedSplit_OnePass(benchmark::State& state)     { Parse1Sp...
    function Parse_CachedSplit_PCRE (line 575) | void Parse_CachedSplit_PCRE(benchmark::State& state)        { Parse1Sp...
    function Parse_CachedSplit_RE2 (line 576) | void Parse_CachedSplit_RE2(benchmark::State& state)         { Parse1Sp...
    function Parse_CachedSplit_BitState (line 577) | void Parse_CachedSplit_BitState(benchmark::State& state)    { Parse1Sp...
    function Parse1SplitHard (line 589) | void Parse1SplitHard(benchmark::State& state,
    function Parse_SplitHard_NFA (line 596) | void Parse_SplitHard_NFA(benchmark::State& state)         { Parse1Spli...
    function Parse_SplitHard_PCRE (line 597) | void Parse_SplitHard_PCRE(benchmark::State& state)        { Parse1Spli...
    function Parse_SplitHard_RE2 (line 598) | void Parse_SplitHard_RE2(benchmark::State& state)         { Parse1Spli...
    function Parse_SplitHard_BitState (line 599) | void Parse_SplitHard_BitState(benchmark::State& state)    { Parse1Spli...
    function Parse_CachedSplitHard_NFA (line 608) | void Parse_CachedSplitHard_NFA(benchmark::State& state)       { Parse1...
    function Parse_CachedSplitHard_PCRE (line 609) | void Parse_CachedSplitHard_PCRE(benchmark::State& state)      { Parse1...
    function Parse_CachedSplitHard_RE2 (line 610) | void Parse_CachedSplitHard_RE2(benchmark::State& state)       { Parse1...
    function Parse_CachedSplitHard_BitState (line 611) | void Parse_CachedSplitHard_BitState(benchmark::State& state)  { Parse1...
    function Parse_CachedSplitHard_Backtrack (line 612) | void Parse_CachedSplitHard_Backtrack(benchmark::State& state) { Parse1...
    function Parse1SplitBig1 (line 624) | void Parse1SplitBig1(benchmark::State& state,
    function Parse_CachedSplitBig1_PCRE (line 634) | void Parse_CachedSplitBig1_PCRE(benchmark::State& state)      { Parse1...
    function Parse_CachedSplitBig1_RE2 (line 635) | void Parse_CachedSplitBig1_RE2(benchmark::State& state)       { Parse1...
    function Parse1SplitBig2 (line 644) | void Parse1SplitBig2(benchmark::State& state,
    function Parse_CachedSplitBig2_PCRE (line 654) | void Parse_CachedSplitBig2_PCRE(benchmark::State& state)      { Parse1...
    function Parse_CachedSplitBig2_RE2 (line 655) | void Parse_CachedSplitBig2_RE2(benchmark::State& state)       { Parse1...
    function ParseRegexp (line 665) | void ParseRegexp(benchmark::State& state, const std::string& regexp) {
    function SimplifyRegexp (line 673) | void SimplifyRegexp(benchmark::State& state, const std::string& regexp) {
    function NullWalkRegexp (line 684) | void NullWalkRegexp(benchmark::State& state, const std::string& regexp) {
    function SimplifyCompileRegexp (line 693) | void SimplifyCompileRegexp(benchmark::State& state, const std::string&...
    function CompileRegexp (line 707) | void CompileRegexp(benchmark::State& state, const std::string& regexp) {
    function CompileToProg (line 718) | void CompileToProg(benchmark::State& state, const std::string& regexp) {
    function CompileByteMap (line 729) | void CompileByteMap(benchmark::State& state, const std::string& regexp) {
    function CompilePCRE (line 741) | void CompilePCRE(benchmark::State& state, const std::string& regexp) {
    function CompileRE2 (line 748) | void CompileRE2(benchmark::State& state, const std::string& regexp) {
    function RunBuild (line 755) | void RunBuild(benchmark::State& state, const std::string& regexp,
    function BM_PCRE_Compile (line 768) | void BM_PCRE_Compile(benchmark::State& state)             { RunBuild(s...
    function BM_Regexp_Parse (line 769) | void BM_Regexp_Parse(benchmark::State& state)             { RunBuild(s...
    function BM_Regexp_Simplify (line 770) | void BM_Regexp_Simplify(benchmark::State& state)          { RunBuild(s...
    function BM_CompileToProg (line 771) | void BM_CompileToProg(benchmark::State& state)            { RunBuild(s...
    function BM_CompileByteMap (line 772) | void BM_CompileByteMap(benchmark::State& state)           { RunBuild(s...
    function BM_Regexp_Compile (line 773) | void BM_Regexp_Compile(benchmark::State& state)           { RunBuild(s...
    function BM_Regexp_SimplifyCompile (line 774) | void BM_Regexp_SimplifyCompile(benchmark::State& state)   { RunBuild(s...
    function BM_Regexp_NullWalk (line 775) | void BM_Regexp_NullWalk(benchmark::State& state)          { RunBuild(s...
    function BM_RE2_Compile (line 776) | void BM_RE2_Compile(benchmark::State& state)              { RunBuild(s...
    function SearchPhone (line 792) | void SearchPhone(benchmark::State& state, ParseImpl* search) {
    function SearchPhone_CachedPCRE (line 799) | void SearchPhone_CachedPCRE(benchmark::State& state) {
    function SearchPhone_CachedRE2 (line 803) | void SearchPhone_CachedRE2(benchmark::State& state) {
    function SearchDFA (line 865) | void SearchDFA(benchmark::State& state, const char* regexp,
    function SearchNFA (line 883) | void SearchNFA(benchmark::State& state, const char* regexp,
    function SearchOnePass (line 899) | void SearchOnePass(benchmark::State& state, const char* regexp,
    function SearchBitState (line 916) | void SearchBitState(benchmark::State& state, const char* regexp,
    function SearchPCRE (line 933) | void SearchPCRE(benchmark::State& state, const char* regexp,
    function SearchRE2 (line 947) | void SearchRE2(benchmark::State& state, const char* regexp,
    function Prog (line 965) | Prog* GetCachedProg(const char* regexp) {
    function PCRE (line 983) | PCRE* GetCachedPCRE(const char* regexp) {
    function RE2 (line 996) | RE2* GetCachedRE2(const char* regexp) {
    function SearchCachedDFA (line 1009) | void SearchCachedDFA(benchmark::State& state, const char* regexp,
    function SearchCachedNFA (line 1022) | void SearchCachedNFA(benchmark::State& state, const char* regexp,
    function SearchCachedOnePass (line 1033) | void SearchCachedOnePass(benchmark::State& state, const char* regexp,
    function SearchCachedBitState (line 1045) | void SearchCachedBitState(benchmark::State& state, const char* regexp,
    function SearchCachedPCRE (line 1057) | void SearchCachedPCRE(benchmark::State& state, const char* regexp,
    function SearchCachedRE2 (line 1070) | void SearchCachedRE2(benchmark::State& state, const char* regexp,
    function Parse3NFA (line 1086) | void Parse3NFA(benchmark::State& state, const char* regexp,
    function Parse3OnePass (line 1101) | void Parse3OnePass(benchmark::State& state, const char* regexp,
    function Parse3BitState (line 1117) | void Parse3BitState(benchmark::State& state, const char* regexp,
    function Parse3Backtrack (line 1133) | void Parse3Backtrack(benchmark::State& state, const char* regexp,
    function Parse3PCRE (line 1148) | void Parse3PCRE(benchmark::State& state, const char* regexp,
    function Parse3RE2 (line 1158) | void Parse3RE2(benchmark::State& state, const char* regexp,
    function Parse3CachedNFA (line 1168) | void Parse3CachedNFA(benchmark::State& state, const char* regexp,
    function Parse3CachedOnePass (line 1178) | void Parse3CachedOnePass(benchmark::State& state, const char* regexp,
    function Parse3CachedBitState (line 1189) | void Parse3CachedBitState(benchmark::State& state, const char* regexp,
    function Parse3CachedBacktrack (line 1200) | void Parse3CachedBacktrack(benchmark::State& state, const char* regexp,
    function Parse3CachedPCRE (line 1210) | void Parse3CachedPCRE(benchmark::State& state, const char* regexp,
    function Parse3CachedRE2 (line 1219) | void Parse3CachedRE2(benchmark::State& state, const char* regexp,
    function Parse1NFA (line 1231) | void Parse1NFA(benchmark::State& state, const char* regexp,
    function Parse1OnePass (line 1246) | void Parse1OnePass(benchmark::State& state, const char* regexp,
    function Parse1BitState (line 1262) | void Parse1BitState(benchmark::State& state, const char* regexp,
    function Parse1PCRE (line 1278) | void Parse1PCRE(benchmark::State& state, const char* regexp,
    function Parse1RE2 (line 1288) | void Parse1RE2(benchmark::State& state, const char* regexp,
    function Parse1CachedNFA (line 1298) | void Parse1CachedNFA(benchmark::State& state, const char* regexp,
    function Parse1CachedOnePass (line 1308) | void Parse1CachedOnePass(benchmark::State& state, const char* regexp,
    function Parse1CachedBitState (line 1319) | void Parse1CachedBitState(benchmark::State& state, const char* regexp,
    function Parse1CachedBacktrack (line 1330) | void Parse1CachedBacktrack(benchmark::State& state, const char* regexp,
    function Parse1CachedPCRE (line 1340) | void Parse1CachedPCRE(benchmark::State& state, const char* regexp,
    function Parse1CachedRE2 (line 1349) | void Parse1CachedRE2(benchmark::State& state, const char* regexp,
    function SearchParse2CachedPCRE (line 1358) | void SearchParse2CachedPCRE(benchmark::State& state, const char* regexp,
    function SearchParse2CachedRE2 (line 1367) | void SearchParse2CachedRE2(benchmark::State& state, const char* regexp,
    function SearchParse1CachedPCRE (line 1376) | void SearchParse1CachedPCRE(benchmark::State& state, const char* regexp,
    function SearchParse1CachedRE2 (line 1385) | void SearchParse1CachedRE2(benchmark::State& state, const char* regexp,
    function EmptyPartialMatchPCRE (line 1394) | void EmptyPartialMatchPCRE(benchmark::State& state) {
    function EmptyPartialMatchRE2 (line 1401) | void EmptyPartialMatchRE2(benchmark::State& state) {
    function SimplePartialMatchPCRE (line 1412) | void SimplePartialMatchPCRE(benchmark::State& state) {
    function SimplePartialMatchRE2 (line 1419) | void SimplePartialMatchRE2(benchmark::State& state) {
    function HTTPPartialMatchPCRE (line 1434) | void HTTPPartialMatchPCRE(benchmark::State& state) {
    function HTTPPartialMatchRE2 (line 1442) | void HTTPPartialMatchRE2(benchmark::State& state) {
    function SmallHTTPPartialMatchPCRE (line 1458) | void SmallHTTPPartialMatchPCRE(benchmark::State& state) {
    function SmallHTTPPartialMatchRE2 (line 1466) | void SmallHTTPPartialMatchRE2(benchmark::State& state) {
    function DotMatchPCRE (line 1479) | void DotMatchPCRE(benchmark::State& state) {
    function DotMatchRE2 (line 1487) | void DotMatchRE2(benchmark::State& state) {
    function ASCIIMatchPCRE (line 1500) | void ASCIIMatchPCRE(benchmark::State& state) {
    function ASCIIMatchRE2 (line 1508) | void ASCIIMatchRE2(benchmark::State& state) {
    function FullMatchPCRE (line 1521) | void FullMatchPCRE(benchmark::State& state, const char *regexp) {
    function FullMatchRE2 (line 1531) | void FullMatchRE2(benchmark::State& state, const char *regexp) {
    function FullMatch_DotStar_CachedPCRE (line 1541) | void FullMatch_DotStar_CachedPCRE(benchmark::State& state) {
    function FullMatch_DotStar_CachedRE2 (line 1544) | void FullMatch_DotStar_CachedRE2(benchmark::State& state) {
    function FullMatch_DotStarDollar_CachedPCRE (line 1548) | void FullMatch_DotStarDollar_CachedPCRE(benchmark::State& state) {
    function FullMatch_DotStarDollar_CachedRE2 (line 1551) | void FullMatch_DotStarDollar_CachedRE2(benchmark::State& state) {
    function FullMatch_DotStarCapture_CachedPCRE (line 1555) | void FullMatch_DotStarCapture_CachedPCRE(benchmark::State& state) {
    function FullMatch_DotStarCapture_CachedRE2 (line 1558) | void FullMatch_DotStarCapture_CachedRE2(benchmark::State& state) {
    function PossibleMatchRangeCommon (line 1577) | void PossibleMatchRangeCommon(benchmark::State& state, const char* reg...
    function PossibleMatchRange_Trivial (line 1587) | void PossibleMatchRange_Trivial(benchmark::State& state) {
    function PossibleMatchRange_Complex (line 1590) | void PossibleMatchRange_Complex(benchmark::State& state) {
    function PossibleMatchRange_Prefix (line 1593) | void PossibleMatchRange_Prefix(benchmark::State& state) {
    function PossibleMatchRange_NoProg (line 1596) | void PossibleMatchRange_NoProg(benchmark::State& state) {
  type re2 (line 35) | namespace re2 {
    function Test (line 37) | void Test() {
    function MemoryUsage (line 57) | void MemoryUsage() {
    function NumCPUs (line 126) | int NumCPUs() {
    function RandomText (line 161) | std::string RandomText(int64_t nbytes) {
    function Search (line 182) | void Search(benchmark::State& state, const char* regexp, SearchImpl* s...
    function Search_Easy0_CachedDFA (line 212) | void Search_Easy0_CachedDFA(benchmark::State& state)     { Search(stat...
    function Search_Easy0_CachedNFA (line 213) | void Search_Easy0_CachedNFA(benchmark::State& state)     { Search(stat...
    function Search_Easy0_CachedPCRE (line 214) | void Search_Easy0_CachedPCRE(benchmark::State& state)    { Search(stat...
    function Search_Easy0_CachedRE2 (line 215) | void Search_Easy0_CachedRE2(benchmark::State& state)     { Search(stat...
    function Search_Easy1_CachedDFA (line 224) | void Search_Easy1_CachedDFA(benchmark::State& state)     { Search(stat...
    function Search_Easy1_CachedNFA (line 225) | void Search_Easy1_CachedNFA(benchmark::State& state)     { Search(stat...
    function Search_Easy1_CachedPCRE (line 226) | void Search_Easy1_CachedPCRE(benchmark::State& state)    { Search(stat...
    function Search_Easy1_CachedRE2 (line 227) | void Search_Easy1_CachedRE2(benchmark::State& state)     { Search(stat...
    function Search_Easy2_CachedDFA (line 236) | void Search_Easy2_CachedDFA(benchmark::State& state)     { Search(stat...
    function Search_Easy2_CachedNFA (line 237) | void Search_Easy2_CachedNFA(benchmark::State& state)     { Search(stat...
    function Search_Easy2_CachedPCRE (line 238) | void Search_Easy2_CachedPCRE(benchmark::State& state)    { Search(stat...
    function Search_Easy2_CachedRE2 (line 239) | void Search_Easy2_CachedRE2(benchmark::State& state)     { Search(stat...
    function Search_Medium_CachedDFA (line 248) | void Search_Medium_CachedDFA(benchmark::State& state)     { Search(sta...
    function Search_Medium_CachedNFA (line 249) | void Search_Medium_CachedNFA(benchmark::State& state)     { Search(sta...
    function Search_Medium_CachedPCRE (line 250) | void Search_Medium_CachedPCRE(benchmark::State& state)    { Search(sta...
    function Search_Medium_CachedRE2 (line 251) | void Search_Medium_CachedRE2(benchmark::State& state)     { Search(sta...
    function Search_Hard_CachedDFA (line 260) | void Search_Hard_CachedDFA(benchmark::State& state)     { Search(state...
    function Search_Hard_CachedNFA (line 261) | void Search_Hard_CachedNFA(benchmark::State& state)     { Search(state...
    function Search_Hard_CachedPCRE (line 262) | void Search_Hard_CachedPCRE(benchmark::State& state)    { Search(state...
    function Search_Hard_CachedRE2 (line 263) | void Search_Hard_CachedRE2(benchmark::State& state)     { Search(state...
    function Search_Fanout_CachedDFA (line 272) | void Search_Fanout_CachedDFA(benchmark::State& state)     { Search(sta...
    function Search_Fanout_CachedNFA (line 273) | void Search_Fanout_CachedNFA(benchmark::State& state)     { Search(sta...
    function Search_Fanout_CachedPCRE (line 274) | void Search_Fanout_CachedPCRE(benchmark::State& state)    { Search(sta...
    function Search_Fanout_CachedRE2 (line 275) | void Search_Fanout_CachedRE2(benchmark::State& state)     { Search(sta...
    function Search_Parens_CachedDFA (line 284) | void Search_Parens_CachedDFA(benchmark::State& state)     { Search(sta...
    function Search_Parens_CachedNFA (line 285) | void Search_Parens_CachedNFA(benchmark::State& state)     { Search(sta...
    function Search_Parens_CachedPCRE (line 286) | void Search_Parens_CachedPCRE(benchmark::State& state)    { Search(sta...
    function Search_Parens_CachedRE2 (line 287) | void Search_Parens_CachedRE2(benchmark::State& state)     { Search(sta...
    function SearchBigFixed (line 296) | void SearchBigFixed(benchmark::State& state, SearchImpl* search) {
    function Search_BigFixed_CachedDFA (line 306) | void Search_BigFixed_CachedDFA(benchmark::State& state)     { SearchBi...
    function Search_BigFixed_CachedNFA (line 307) | void Search_BigFixed_CachedNFA(benchmark::State& state)     { SearchBi...
    function Search_BigFixed_CachedPCRE (line 308) | void Search_BigFixed_CachedPCRE(benchmark::State& state)    { SearchBi...
    function Search_BigFixed_CachedRE2 (line 309) | void Search_BigFixed_CachedRE2(benchmark::State& state)     { SearchBi...
    function FindAndConsume (line 320) | void FindAndConsume(benchmark::State& state) {
    function SearchSuccess (line 337) | void SearchSuccess(benchmark::State& state, const char* regexp,
    function Search_Success_DFA (line 346) | void Search_Success_DFA(benchmark::State& state)     { SearchSuccess(s...
    function Search_Success_NFA (line 347) | void Search_Success_NFA(benchmark::State& state)     { SearchSuccess(s...
    function Search_Success_PCRE (line 348) | void Search_Success_PCRE(benchmark::State& state)    { SearchSuccess(s...
    function Search_Success_RE2 (line 349) | void Search_Success_RE2(benchmark::State& state)     { SearchSuccess(s...
    function Search_Success_OnePass (line 350) | void Search_Success_OnePass(benchmark::State& state) { SearchSuccess(s...
    function Search_Success_CachedDFA (line 360) | void Search_Success_CachedDFA(benchmark::State& state)     { SearchSuc...
    function Search_Success_CachedNFA (line 361) | void Search_Success_CachedNFA(benchmark::State& state)     { SearchSuc...
    function Search_Success_CachedPCRE (line 362) | void Search_Success_CachedPCRE(benchmark::State& state)    { SearchSuc...
    function Search_Success_CachedRE2 (line 363) | void Search_Success_CachedRE2(benchmark::State& state)     { SearchSuc...
    function Search_Success_CachedOnePass (line 364) | void Search_Success_CachedOnePass(benchmark::State& state) { SearchSuc...
    function Search_Success1_DFA (line 377) | void Search_Success1_DFA(benchmark::State& state)      { SearchSuccess...
    function Search_Success1_NFA (line 378) | void Search_Success1_NFA(benchmark::State& state)      { SearchSuccess...
    function Search_Success1_PCRE (line 379) | void Search_Success1_PCRE(benchmark::State& state)     { SearchSuccess...
    function Search_Success1_RE2 (line 380) | void Search_Success1_RE2(benchmark::State& state)      { SearchSuccess...
    function Search_Success1_BitState (line 381) | void Search_Success1_BitState(benchmark::State& state) { SearchSuccess...
    function Search_Success1_CachedDFA (line 391) | void Search_Success1_CachedDFA(benchmark::State& state)      { SearchS...
    function Search_Success1_CachedNFA (line 392) | void Search_Success1_CachedNFA(benchmark::State& state)      { SearchS...
    function Search_Success1_CachedPCRE (line 393) | void Search_Success1_CachedPCRE(benchmark::State& state)     { SearchS...
    function Search_Success1_CachedRE2 (line 394) | void Search_Success1_CachedRE2(benchmark::State& state)      { SearchS...
    function Search_Success1_CachedBitState (line 395) | void Search_Success1_CachedBitState(benchmark::State& state) { SearchS...
    function SearchAltMatch (line 408) | void SearchAltMatch(benchmark::State& state, SearchImpl* search) {
    function Search_AltMatch_DFA (line 414) | void Search_AltMatch_DFA(benchmark::State& state)      { SearchAltMatc...
    function Search_AltMatch_NFA (line 415) | void Search_AltMatch_NFA(benchmark::State& state)      { SearchAltMatc...
    function Search_AltMatch_OnePass (line 416) | void Search_AltMatch_OnePass(benchmark::State& state)  { SearchAltMatc...
    function Search_AltMatch_BitState (line 417) | void Search_AltMatch_BitState(benchmark::State& state) { SearchAltMatc...
    function Search_AltMatch_PCRE (line 418) | void Search_AltMatch_PCRE(benchmark::State& state)     { SearchAltMatc...
    function Search_AltMatch_RE2 (line 419) | void Search_AltMatch_RE2(benchmark::State& state)      { SearchAltMatc...
    function Search_AltMatch_CachedDFA (line 430) | void Search_AltMatch_CachedDFA(benchmark::State& state)      { SearchA...
    function Search_AltMatch_CachedNFA (line 431) | void Search_AltMatch_CachedNFA(benchmark::State& state)      { SearchA...
    function Search_AltMatch_CachedOnePass (line 432) | void Search_AltMatch_CachedOnePass(benchmark::State& state)  { SearchA...
    function Search_AltMatch_CachedBitState (line 433) | void Search_AltMatch_CachedBitState(benchmark::State& state) { SearchA...
    function Search_AltMatch_CachedPCRE (line 434) | void Search_AltMatch_CachedPCRE(benchmark::State& state)     { SearchA...
    function Search_AltMatch_CachedRE2 (line 435) | void Search_AltMatch_CachedRE2(benchmark::State& state)      { SearchA...
    function SearchDigits (line 448) | void SearchDigits(benchmark::State& state, SearchImpl* search) {
    function Search_Digits_DFA (line 454) | void Search_Digits_DFA(benchmark::State& state)         { SearchDigits...
    function Search_Digits_NFA (line 455) | void Search_Digits_NFA(benchmark::State& state)         { SearchDigits...
    function Search_Digits_OnePass (line 456) | void Search_Digits_OnePass(benchmark::State& state)     { SearchDigits...
    function Search_Digits_PCRE (line 457) | void Search_Digits_PCRE(benchmark::State& state)        { SearchDigits...
    function Search_Digits_RE2 (line 458) | void Search_Digits_RE2(benchmark::State& state)         { SearchDigits...
    function Search_Digits_BitState (line 459) | void Search_Digits_BitState(benchmark::State& state)    { SearchDigits...
    function Parse3Digits (line 472) | void Parse3Digits(benchmark::State& state,
    function Parse_Digits_NFA (line 479) | void Parse_Digits_NFA(benchmark::State& state)         { Parse3Digits(...
    function Parse_Digits_OnePass (line 480) | void Parse_Digits_OnePass(benchmark::State& state)     { Parse3Digits(...
    function Parse_Digits_PCRE (line 481) | void Parse_Digits_PCRE(benchmark::State& state)        { Parse3Digits(...
    function Parse_Digits_RE2 (line 482) | void Parse_Digits_RE2(benchmark::State& state)         { Parse3Digits(...
    function Parse_Digits_Backtrack (line 483) | void Parse_Digits_Backtrack(benchmark::State& state)   { Parse3Digits(...
    function Parse_Digits_BitState (line 484) | void Parse_Digits_BitState(benchmark::State& state)    { Parse3Digits(...
    function Parse_CachedDigits_NFA (line 495) | void Parse_CachedDigits_NFA(benchmark::State& state)         { Parse3D...
    function Parse_CachedDigits_OnePass (line 496) | void Parse_CachedDigits_OnePass(benchmark::State& state)     { Parse3D...
    function Parse_CachedDigits_PCRE (line 497) | void Parse_CachedDigits_PCRE(benchmark::State& state)        { Parse3D...
    function Parse_CachedDigits_RE2 (line 498) | void Parse_CachedDigits_RE2(benchmark::State& state)         { Parse3D...
    function Parse_CachedDigits_Backtrack (line 499) | void Parse_CachedDigits_Backtrack(benchmark::State& state)   { Parse3D...
    function Parse_CachedDigits_BitState (line 500) | void Parse_CachedDigits_BitState(benchmark::State& state)    { Parse3D...
    function Parse3DigitDs (line 511) | void Parse3DigitDs(benchmark::State& state,
    function Parse_DigitDs_NFA (line 518) | void Parse_DigitDs_NFA(benchmark::State& state)         { Parse3DigitD...
    function Parse_DigitDs_OnePass (line 519) | void Parse_DigitDs_OnePass(benchmark::State& state)     { Parse3DigitD...
    function Parse_DigitDs_PCRE (line 520) | void Parse_DigitDs_PCRE(benchmark::State& state)        { Parse3DigitD...
    function Parse_DigitDs_RE2 (line 521) | void Parse_DigitDs_RE2(benchmark::State& state)         { Parse3DigitD...
    function Parse_DigitDs_Backtrack (line 522) | void Parse_DigitDs_Backtrack(benchmark::State& state)   { Parse3DigitD...
    function Parse_DigitDs_BitState (line 523) | void Parse_DigitDs_BitState(benchmark::State& state)    { Parse3DigitD...
    function Parse_CachedDigitDs_NFA (line 534) | void Parse_CachedDigitDs_NFA(benchmark::State& state)         { Parse3...
    function Parse_CachedDigitDs_OnePass (line 535) | void Parse_CachedDigitDs_OnePass(benchmark::State& state)     { Parse3...
    function Parse_CachedDigitDs_PCRE (line 536) | void Parse_CachedDigitDs_PCRE(benchmark::State& state)        { Parse3...
    function Parse_CachedDigitDs_RE2 (line 537) | void Parse_CachedDigitDs_RE2(benchmark::State& state)         { Parse3...
    function Parse_CachedDigitDs_Backtrack (line 538) | void Parse_CachedDigitDs_Backtrack(benchmark::State& state)   { Parse3...
    function Parse_CachedDigitDs_BitState (line 539) | void Parse_CachedDigitDs_BitState(benchmark::State& state)    { Parse3...
    function Parse1Split (line 552) | void Parse1Split(benchmark::State& state,
    function Parse_Split_NFA (line 559) | void Parse_Split_NFA(benchmark::State& state)         { Parse1Split(st...
    function Parse_Split_OnePass (line 560) | void Parse_Split_OnePass(benchmark::State& state)     { Parse1Split(st...
    function Parse_Split_PCRE (line 561) | void Parse_Split_PCRE(benchmark::State& state)        { Parse1Split(st...
    function Parse_Split_RE2 (line 562) | void Parse_Split_RE2(benchmark::State& state)         { Parse1Split(st...
    function Parse_Split_BitState (line 563) | void Parse_Split_BitState(benchmark::State& state)    { Parse1Split(st...
    function Parse_CachedSplit_NFA (line 573) | void Parse_CachedSplit_NFA(benchmark::State& state)         { Parse1Sp...
    function Parse_CachedSplit_OnePass (line 574) | void Parse_CachedSplit_OnePass(benchmark::State& state)     { Parse1Sp...
    function Parse_CachedSplit_PCRE (line 575) | void Parse_CachedSplit_PCRE(benchmark::State& state)        { Parse1Sp...
    function Parse_CachedSplit_RE2 (line 576) | void Parse_CachedSplit_RE2(benchmark::State& state)         { Parse1Sp...
    function Parse_CachedSplit_BitState (line 577) | void Parse_CachedSplit_BitState(benchmark::State& state)    { Parse1Sp...
    function Parse1SplitHard (line 589) | void Parse1SplitHard(benchmark::State& state,
    function Parse_SplitHard_NFA (line 596) | void Parse_SplitHard_NFA(benchmark::State& state)         { Parse1Spli...
    function Parse_SplitHard_PCRE (line 597) | void Parse_SplitHard_PCRE(benchmark::State& state)        { Parse1Spli...
    function Parse_SplitHard_RE2 (line 598) | void Parse_SplitHard_RE2(benchmark::State& state)         { Parse1Spli...
    function Parse_SplitHard_BitState (line 599) | void Parse_SplitHard_BitState(benchmark::State& state)    { Parse1Spli...
    function Parse_CachedSplitHard_NFA (line 608) | void Parse_CachedSplitHard_NFA(benchmark::State& state)       { Parse1...
    function Parse_CachedSplitHard_PCRE (line 609) | void Parse_CachedSplitHard_PCRE(benchmark::State& state)      { Parse1...
    function Parse_CachedSplitHard_RE2 (line 610) | void Parse_CachedSplitHard_RE2(benchmark::State& state)       { Parse1...
    function Parse_CachedSplitHard_BitState (line 611) | void Parse_CachedSplitHard_BitState(benchmark::State& state)  { Parse1...
    function Parse_CachedSplitHard_Backtrack (line 612) | void Parse_CachedSplitHard_Backtrack(benchmark::State& state) { Parse1...
    function Parse1SplitBig1 (line 624) | void Parse1SplitBig1(benchmark::State& state,
    function Parse_CachedSplitBig1_PCRE (line 634) | void Parse_CachedSplitBig1_PCRE(benchmark::State& state)      { Parse1...
    function Parse_CachedSplitBig1_RE2 (line 635) | void Parse_CachedSplitBig1_RE2(benchmark::State& state)       { Parse1...
    function Parse1SplitBig2 (line 644) | void Parse1SplitBig2(benchmark::State& state,
    function Parse_CachedSplitBig2_PCRE (line 654) | void Parse_CachedSplitBig2_PCRE(benchmark::State& state)      { Parse1...
    function Parse_CachedSplitBig2_RE2 (line 655) | void Parse_CachedSplitBig2_RE2(benchmark::State& state)       { Parse1...
    function ParseRegexp (line 665) | void ParseRegexp(benchmark::State& state, const std::string& regexp) {
    function SimplifyRegexp (line 673) | void SimplifyRegexp(benchmark::State& state, const std::string& regexp) {
    function NullWalkRegexp (line 684) | void NullWalkRegexp(benchmark::State& state, const std::string& regexp) {
    function SimplifyCompileRegexp (line 693) | void SimplifyCompileRegexp(benchmark::State& state, const std::string&...
    function CompileRegexp (line 707) | void CompileRegexp(benchmark::State& state, const std::string& regexp) {
    function CompileToProg (line 718) | void CompileToProg(benchmark::State& state, const std::string& regexp) {
    function CompileByteMap (line 729) | void CompileByteMap(benchmark::State& state, const std::string& regexp) {
    function CompilePCRE (line 741) | void CompilePCRE(benchmark::State& state, const std::string& regexp) {
    function CompileRE2 (line 748) | void CompileRE2(benchmark::State& state, const std::string& regexp) {
    function RunBuild (line 755) | void RunBuild(benchmark::State& state, const std::string& regexp,
    function BM_PCRE_Compile (line 768) | void BM_PCRE_Compile(benchmark::State& state)             { RunBuild(s...
    function BM_Regexp_Parse (line 769) | void BM_Regexp_Parse(benchmark::State& state)             { RunBuild(s...
    function BM_Regexp_Simplify (line 770) | void BM_Regexp_Simplify(benchmark::State& state)          { RunBuild(s...
    function BM_CompileToProg (line 771) | void BM_CompileToProg(benchmark::State& state)            { RunBuild(s...
    function BM_CompileByteMap (line 772) | void BM_CompileByteMap(benchmark::State& state)           { RunBuild(s...
    function BM_Regexp_Compile (line 773) | void BM_Regexp_Compile(benchmark::State& state)           { RunBuild(s...
    function BM_Regexp_SimplifyCompile (line 774) | void BM_Regexp_SimplifyCompile(benchmark::State& state)   { RunBuild(s...
    function BM_Regexp_NullWalk (line 775) | void BM_Regexp_NullWalk(benchmark::State& state)          { RunBuild(s...
    function BM_RE2_Compile (line 776) | void BM_RE2_Compile(benchmark::State& state)              { RunBuild(s...
    function SearchPhone (line 792) | void SearchPhone(benchmark::State& state, ParseImpl* search) {
    function SearchPhone_CachedPCRE (line 799) | void SearchPhone_CachedPCRE(benchmark::State& state) {
    function SearchPhone_CachedRE2 (line 803) | void SearchPhone_CachedRE2(benchmark::State& state) {
    function SearchDFA (line 865) | void SearchDFA(benchmark::State& state, const char* regexp,
    function SearchNFA (line 883) | void SearchNFA(benchmark::State& state, const char* regexp,
    function SearchOnePass (line 899) | void SearchOnePass(benchmark::State& state, const char* regexp,
    function SearchBitState (line 916) | void SearchBitState(benchmark::State& state, const char* regexp,
    function SearchPCRE (line 933) | void SearchPCRE(benchmark::State& state, const char* regexp,
    function SearchRE2 (line 947) | void SearchRE2(benchmark::State& state, const char* regexp,
    function Prog (line 965) | Prog* GetCachedProg(const char* regexp) {
    function PCRE (line 983) | PCRE* GetCachedPCRE(const char* regexp) {
    function RE2 (line 996) | RE2* GetCachedRE2(const char* regexp) {
    function SearchCachedDFA (line 1009) | void SearchCachedDFA(benchmark::State& state, const char* regexp,
    function SearchCachedNFA (line 1022) | void SearchCachedNFA(benchmark::State& state, const char* regexp,
    function SearchCachedOnePass (line 1033) | void SearchCachedOnePass(benchmark::State& state, const char* regexp,
    function SearchCachedBitState (line 1045) | void SearchCachedBitState(benchmark::State& state, const char* regexp,
    function SearchCachedPCRE (line 1057) | void SearchCachedPCRE(benchmark::State& state, const char* regexp,
    function SearchCachedRE2 (line 1070) | void SearchCachedRE2(benchmark::State& state, const char* regexp,
    function Parse3NFA (line 1086) | void Parse3NFA(benchmark::State& state, const char* regexp,
    function Parse3OnePass (line 1101) | void Parse3OnePass(benchmark::State& state, const char* regexp,
    function Parse3BitState (line 1117) | void Parse3BitState(benchmark::State& state, const char* regexp,
    function Parse3Backtrack (line 1133) | void Parse3Backtrack(benchmark::State& state, const char* regexp,
    function Parse3PCRE (line 1148) | void Parse3PCRE(benchmark::State& state, const char* regexp,
    function Parse3RE2 (line 1158) | void Parse3RE2(benchmark::State& state, const char* regexp,
    function Parse3CachedNFA (line 1168) | void Parse3CachedNFA(benchmark::State& state, const char* regexp,
    function Parse3CachedOnePass (line 1178) | void Parse3CachedOnePass(benchmark::State& state, const char* regexp,
    function Parse3CachedBitState (line 1189) | void Parse3CachedBitState(benchmark::State& state, const char* regexp,
    function Parse3CachedBacktrack (line 1200) | void Parse3CachedBacktrack(benchmark::State& state, const char* regexp,
    function Parse3CachedPCRE (line 1210) | void Parse3CachedPCRE(benchmark::State& state, const char* regexp,
    function Parse3CachedRE2 (line 1219) | void Parse3CachedRE2(benchmark::State& state, const char* regexp,
    function Parse1NFA (line 1231) | void Parse1NFA(benchmark::State& state, const char* regexp,
    function Parse1OnePass (line 1246) | void Parse1OnePass(benchmark::State& state, const char* regexp,
    function Parse1BitState (line 1262) | void Parse1BitState(benchmark::State& state, const char* regexp,
    function Parse1PCRE (line 1278) | void Parse1PCRE(benchmark::State& state, const char* regexp,
    function Parse1RE2 (line 1288) | void Parse1RE2(benchmark::State& state, const char* regexp,
    function Parse1CachedNFA (line 1298) | void Parse1CachedNFA(benchmark::State& state, const char* regexp,
    function Parse1CachedOnePass (line 1308) | void Parse1CachedOnePass(benchmark::State& state, const char* regexp,
    function Parse1CachedBitState (line 1319) | void Parse1CachedBitState(benchmark::State& state, const char* regexp,
    function Parse1CachedBacktrack (line 1330) | void Parse1CachedBacktrack(benchmark::State& state, const char* regexp,
    function Parse1CachedPCRE (line 1340) | void Parse1CachedPCRE(benchmark::State& state, const char* regexp,
    function Parse1CachedRE2 (line 1349) | void Parse1CachedRE2(benchmark::State& state, const char* regexp,
    function SearchParse2CachedPCRE (line 1358) | void SearchParse2CachedPCRE(benchmark::State& state, const char* regexp,
    function SearchParse2CachedRE2 (line 1367) | void SearchParse2CachedRE2(benchmark::State& state, const char* regexp,
    function SearchParse1CachedPCRE (line 1376) | void SearchParse1CachedPCRE(benchmark::State& state, const char* regexp,
    function SearchParse1CachedRE2 (line 1385) | void SearchParse1CachedRE2(benchmark::State& state, const char* regexp,
    function EmptyPartialMatchPCRE (line 1394) | void EmptyPartialMatchPCRE(benchmark::State& state) {
    function EmptyPartialMatchRE2 (line 1401) | void EmptyPartialMatchRE2(benchmark::State& state) {
    function SimplePartialMatchPCRE (line 1412) | void SimplePartialMatchPCRE(benchmark::State& state) {
    function SimplePartialMatchRE2 (line 1419) | void SimplePartialMatchRE2(benchmark::State& state) {
    function HTTPPartialMatchPCRE (line 1434) | void HTTPPartialMatchPCRE(benchmark::State& state) {
    function HTTPPartialMatchRE2 (line 1442) | void HTTPPartialMatchRE2(benchmark::State& state) {
    function SmallHTTPPartialMatchPCRE (line 1458) | void SmallHTTPPartialMatchPCRE(benchmark::State& state) {
    function SmallHTTPPartialMatchRE2 (line 1466) | void SmallHTTPPartialMatchRE2(benchmark::State& state) {
    function DotMatchPCRE (line 1479) | void DotMatchPCRE(benchmark::State& state) {
    function DotMatchRE2 (line 1487) | void DotMatchRE2(benchmark::State& state) {
    function ASCIIMatchPCRE (line 1500) | void ASCIIMatchPCRE(benchmark::State& state) {
    function ASCIIMatchRE2 (line 1508) | void ASCIIMatchRE2(benchmark::State& state) {
    function FullMatchPCRE (line 1521) | void FullMatchPCRE(benchmark::State& state, const char *regexp) {
    function FullMatchRE2 (line 1531) | void FullMatchRE2(benchmark::State& state, const char *regexp) {
    function FullMatch_DotStar_CachedPCRE (line 1541) | void FullMatch_DotStar_CachedPCRE(benchmark::State& state) {
    function FullMatch_DotStar_CachedRE2 (line 1544) | void FullMatch_DotStar_CachedRE2(benchmark::State& state) {
    function FullMatch_DotStarDollar_CachedPCRE (line 1548) | void FullMatch_DotStarDollar_CachedPCRE(benchmark::State& state) {
    function FullMatch_DotStarDollar_CachedRE2 (line 1551) | void FullMatch_DotStarDollar_CachedRE2(benchmark::State& state) {
    function FullMatch_DotStarCapture_CachedPCRE (line 1555) | void FullMatch_DotStarCapture_CachedPCRE(benchmark::State& state) {
    function FullMatch_DotStarCapture_CachedRE2 (line 1558) | void FullMatch_DotStarCapture_CachedRE2(benchmark::State& state) {
    function PossibleMatchRangeCommon (line 1577) | void PossibleMatchRangeCommon(benchmark::State& state, const char* reg...
    function PossibleMatchRange_Trivial (line 1587) | void PossibleMatchRange_Trivial(benchmark::State& state) {
    function PossibleMatchRange_Complex (line 1590) | void PossibleMatchRange_Complex(benchmark::State& state) {
    function PossibleMatchRange_Prefix (line 1593) | void PossibleMatchRange_Prefix(benchmark::State& state) {
    function PossibleMatchRange_NoProg (line 1596) | void PossibleMatchRange_NoProg(benchmark::State& state) {
  type re2 (line 766) | namespace re2 {
    function Test (line 37) | void Test() {
    function MemoryUsage (line 57) | void MemoryUsage() {
    function NumCPUs (line 126) | int NumCPUs() {
    function RandomText (line 161) | std::string RandomText(int64_t nbytes) {
    function Search (line 182) | void Search(benchmark::State& state, const char* regexp, SearchImpl* s...
    function Search_Easy0_CachedDFA (line 212) | void Search_Easy0_CachedDFA(benchmark::State& state)     { Search(stat...
    function Search_Easy0_CachedNFA (line 213) | void Search_Easy0_CachedNFA(benchmark::State& state)     { Search(stat...
    function Search_Easy0_CachedPCRE (line 214) | void Search_Easy0_CachedPCRE(benchmark::State& state)    { Search(stat...
    function Search_Easy0_CachedRE2 (line 215) | void Search_Easy0_CachedRE2(benchmark::State& state)     { Search(stat...
    function Search_Easy1_CachedDFA (line 224) | void Search_Easy1_CachedDFA(benchmark::State& state)     { Search(stat...
    function Search_Easy1_CachedNFA (line 225) | void Search_Easy1_CachedNFA(benchmark::State& state)     { Search(stat...
    function Search_Easy1_CachedPCRE (line 226) | void Search_Easy1_CachedPCRE(benchmark::State& state)    { Search(stat...
    function Search_Easy1_CachedRE2 (line 227) | void Search_Easy1_CachedRE2(benchmark::State& state)     { Search(stat...
    function Search_Easy2_CachedDFA (line 236) | void Search_Easy2_CachedDFA(benchmark::State& state)     { Search(stat...
    function Search_Easy2_CachedNFA (line 237) | void Search_Easy2_CachedNFA(benchmark::State& state)     { Search(stat...
    function Search_Easy2_CachedPCRE (line 238) | void Search_Easy2_CachedPCRE(benchmark::State& state)    { Search(stat...
    function Search_Easy2_CachedRE2 (line 239) | void Search_Easy2_CachedRE2(benchmark::State& state)     { Search(stat...
    function Search_Medium_CachedDFA (line 248) | void Search_Medium_CachedDFA(benchmark::State& state)     { Search(sta...
    function Search_Medium_CachedNFA (line 249) | void Search_Medium_CachedNFA(benchmark::State& state)     { Search(sta...
    function Search_Medium_CachedPCRE (line 250) | void Search_Medium_CachedPCRE(benchmark::State& state)    { Search(sta...
    function Search_Medium_CachedRE2 (line 251) | void Search_Medium_CachedRE2(benchmark::State& state)     { Search(sta...
    function Search_Hard_CachedDFA (line 260) | void Search_Hard_CachedDFA(benchmark::State& state)     { Search(state...
    function Search_Hard_CachedNFA (line 261) | void Search_Hard_CachedNFA(benchmark::State& state)     { Search(state...
    function Search_Hard_CachedPCRE (line 262) | void Search_Hard_CachedPCRE(benchmark::State& state)    { Search(state...
    function Search_Hard_CachedRE2 (line 263) | void Search_Hard_CachedRE2(benchmark::State& state)     { Search(state...
    function Search_Fanout_CachedDFA (line 272) | void Search_Fanout_CachedDFA(benchmark::State& state)     { Search(sta...
    function Search_Fanout_CachedNFA (line 273) | void Search_Fanout_CachedNFA(benchmark::State& state)     { Search(sta...
    function Search_Fanout_CachedPCRE (line 274) | void Search_Fanout_CachedPCRE(benchmark::State& state)    { Search(sta...
    function Search_Fanout_CachedRE2 (line 275) | void Search_Fanout_CachedRE2(benchmark::State& state)     { Search(sta...
    function Search_Parens_CachedDFA (line 284) | void Search_Parens_CachedDFA(benchmark::State& state)     { Search(sta...
    function Search_Parens_CachedNFA (line 285) | void Search_Parens_CachedNFA(benchmark::State& state)     { Search(sta...
    function Search_Parens_CachedPCRE (line 286) | void Search_Parens_CachedPCRE(benchmark::State& state)    { Search(sta...
    function Search_Parens_CachedRE2 (line 287) | void Search_Parens_CachedRE2(benchmark::State& state)     { Search(sta...
    function SearchBigFixed (line 296) | void SearchBigFixed(benchmark::State& state, SearchImpl* search) {
    function Search_BigFixed_CachedDFA (line 306) | void Search_BigFixed_CachedDFA(benchmark::State& state)     { SearchBi...
    function Search_BigFixed_CachedNFA (line 307) | void Search_BigFixed_CachedNFA(benchmark::State& state)     { SearchBi...
    function Search_BigFixed_CachedPCRE (line 308) | void Search_BigFixed_CachedPCRE(benchmark::State& state)    { SearchBi...
    function Search_BigFixed_CachedRE2 (line 309) | void Search_BigFixed_CachedRE2(benchmark::State& state)     { SearchBi...
    function FindAndConsume (line 320) | void FindAndConsume(benchmark::State& state) {
    function SearchSuccess (line 337) | void SearchSuccess(benchmark::State& state, const char* regexp,
    function Search_Success_DFA (line 346) | void Search_Success_DFA(benchmark::State& state)     { SearchSuccess(s...
    function Search_Success_NFA (line 347) | void Search_Success_NFA(benchmark::State& state)     { SearchSuccess(s...
    function Search_Success_PCRE (line 348) | void Search_Success_PCRE(benchmark::State& state)    { SearchSuccess(s...
    function Search_Success_RE2 (line 349) | void Search_Success_RE2(benchmark::State& state)     { SearchSuccess(s...
    function Search_Success_OnePass (line 350) | void Search_Success_OnePass(benchmark::State& state) { SearchSuccess(s...
    function Search_Success_CachedDFA (line 360) | void Search_Success_CachedDFA(benchmark::State& state)     { SearchSuc...
    function Search_Success_CachedNFA (line 361) | void Search_Success_CachedNFA(benchmark::State& state)     { SearchSuc...
    function Search_Success_CachedPCRE (line 362) | void Search_Success_CachedPCRE(benchmark::State& state)    { SearchSuc...
    function Search_Success_CachedRE2 (line 363) | void Search_Success_CachedRE2(benchmark::State& state)     { SearchSuc...
    function Search_Success_CachedOnePass (line 364) | void Search_Success_CachedOnePass(benchmark::State& state) { SearchSuc...
    function Search_Success1_DFA (line 377) | void Search_Success1_DFA(benchmark::State& state)      { SearchSuccess...
    function Search_Success1_NFA (line 378) | void Search_Success1_NFA(benchmark::State& state)      { SearchSuccess...
    function Search_Success1_PCRE (line 379) | void Search_Success1_PCRE(benchmark::State& state)     { SearchSuccess...
    function Search_Success1_RE2 (line 380) | void Search_Success1_RE2(benchmark::State& state)      { SearchSuccess...
    function Search_Success1_BitState (line 381) | void Search_Success1_BitState(benchmark::State& state) { SearchSuccess...
    function Search_Success1_CachedDFA (line 391) | void Search_Success1_CachedDFA(benchmark::State& state)      { SearchS...
    function Search_Success1_CachedNFA (line 392) | void Search_Success1_CachedNFA(benchmark::State& state)      { SearchS...
    function Search_Success1_CachedPCRE (line 393) | void Search_Success1_CachedPCRE(benchmark::State& state)     { SearchS...
    function Search_Success1_CachedRE2 (line 394) | void Search_Success1_CachedRE2(benchmark::State& state)      { SearchS...
    function Search_Success1_CachedBitState (line 395) | void Search_Success1_CachedBitState(benchmark::State& state) { SearchS...
    function SearchAltMatch (line 408) | void SearchAltMatch(benchmark::State& state, SearchImpl* search) {
    function Search_AltMatch_DFA (line 414) | void Search_AltMatch_DFA(benchmark::State& state)      { SearchAltMatc...
    function Search_AltMatch_NFA (line 415) | void Search_AltMatch_NFA(benchmark::State& state)      { SearchAltMatc...
    function Search_AltMatch_OnePass (line 416) | void Search_AltMatch_OnePass(benchmark::State& state)  { SearchAltMatc...
    function Search_AltMatch_BitState (line 417) | void Search_AltMatch_BitState(benchmark::State& state) { SearchAltMatc...
    function Search_AltMatch_PCRE (line 418) | void Search_AltMatch_PCRE(benchmark::State& state)     { SearchAltMatc...
    function Search_AltMatch_RE2 (line 419) | void Search_AltMatch_RE2(benchmark::State& state)      { SearchAltMatc...
    function Search_AltMatch_CachedDFA (line 430) | void Search_AltMatch_CachedDFA(benchmark::State& state)      { SearchA...
    function Search_AltMatch_CachedNFA (line 431) | void Search_AltMatch_CachedNFA(benchmark::State& state)      { SearchA...
    function Search_AltMatch_CachedOnePass (line 432) | void Search_AltMatch_CachedOnePass(benchmark::State& state)  { SearchA...
    function Search_AltMatch_CachedBitState (line 433) | void Search_AltMatch_CachedBitState(benchmark::State& state) { SearchA...
    function Search_AltMatch_CachedPCRE (line 434) | void Search_AltMatch_CachedPCRE(benchmark::State& state)     { SearchA...
    function Search_AltMatch_CachedRE2 (line 435) | void Search_AltMatch_CachedRE2(benchmark::State& state)      { SearchA...
    function SearchDigits (line 448) | void SearchDigits(benchmark::State& state, SearchImpl* search) {
    function Search_Digits_DFA (line 454) | void Search_Digits_DFA(benchmark::State& state)         { SearchDigits...
    function Search_Digits_NFA (line 455) | void Search_Digits_NFA(benchmark::State& state)         { SearchDigits...
    function Search_Digits_OnePass (line 456) | void Search_Digits_OnePass(benchmark::State& state)     { SearchDigits...
    function Search_Digits_PCRE (line 457) | void Search_Digits_PCRE(benchmark::State& state)        { SearchDigits...
    function Search_Digits_RE2 (line 458) | void Search_Digits_RE2(benchmark::State& state)         { SearchDigits...
    function Search_Digits_BitState (line 459) | void Search_Digits_BitState(benchmark::State& state)    { SearchDigits...
    function Parse3Digits (line 472) | void Parse3Digits(benchmark::State& state,
    function Parse_Digits_NFA (line 479) | void Parse_Digits_NFA(benchmark::State& state)         { Parse3Digits(...
    function Parse_Digits_OnePass (line 480) | void Parse_Digits_OnePass(benchmark::State& state)     { Parse3Digits(...
    function Parse_Digits_PCRE (line 481) | void Parse_Digits_PCRE(benchmark::State& state)        { Parse3Digits(...
    function Parse_Digits_RE2 (line 482) | void Parse_Digits_RE2(benchmark::State& state)         { Parse3Digits(...
    function Parse_Digits_Backtrack (line 483) | void Parse_Digits_Backtrack(benchmark::State& state)   { Parse3Digits(...
    function Parse_Digits_BitState (line 484) | void Parse_Digits_BitState(benchmark::State& state)    { Parse3Digits(...
    function Parse_CachedDigits_NFA (line 495) | void Parse_CachedDigits_NFA(benchmark::State& state)         { Parse3D...
    function Parse_CachedDigits_OnePass (line 496) | void Parse_CachedDigits_OnePass(benchmark::State& state)     { Parse3D...
    function Parse_CachedDigits_PCRE (line 497) | void Parse_CachedDigits_PCRE(benchmark::State& state)        { Parse3D...
    function Parse_CachedDigits_RE2 (line 498) | void Parse_CachedDigits_RE2(benchmark::State& state)         { Parse3D...
    function Parse_CachedDigits_Backtrack (line 499) | void Parse_CachedDigits_Backtrack(benchmark::State& state)   { Parse3D...
    function Parse_CachedDigits_BitState (line 500) | void Parse_CachedDigits_BitState(benchmark::State& state)    { Parse3D...
    function Parse3DigitDs (line 511) | void Parse3DigitDs(benchmark::State& state,
    function Parse_DigitDs_NFA (line 518) | void Parse_DigitDs_NFA(benchmark::State& state)         { Parse3DigitD...
    function Parse_DigitDs_OnePass (line 519) | void Parse_DigitDs_OnePass(benchmark::State& state)     { Parse3DigitD...
    function Parse_DigitDs_PCRE (line 520) | void Parse_DigitDs_PCRE(benchmark::State& state)        { Parse3DigitD...
    function Parse_DigitDs_RE2 (line 521) | void Parse_DigitDs_RE2(benchmark::State& state)         { Parse3DigitD...
    function Parse_DigitDs_Backtrack (line 522) | void Parse_DigitDs_Backtrack(benchmark::State& state)   { Parse3DigitD...
    function Parse_DigitDs_BitState (line 523) | void Parse_DigitDs_BitState(benchmark::State& state)    { Parse3DigitD...
    function Parse_CachedDigitDs_NFA (line 534) | void Parse_CachedDigitDs_NFA(benchmark::State& state)         { Parse3...
    function Parse_CachedDigitDs_OnePass (line 535) | void Parse_CachedDigitDs_OnePass(benchmark::State& state)     { Parse3...
    function Parse_CachedDigitDs_PCRE (line 536) | void Parse_CachedDigitDs_PCRE(benchmark::State& state)        { Parse3...
    function Parse_CachedDigitDs_RE2 (line 537) | void Parse_CachedDigitDs_RE2(benchmark::State& state)         { Parse3...
    function Parse_CachedDigitDs_Backtrack (line 538) | void Parse_CachedDigitDs_Backtrack(benchmark::State& state)   { Parse3...
    function Parse_CachedDigitDs_BitState (line 539) | void Parse_CachedDigitDs_BitState(benchmark::State& state)    { Parse3...
    function Parse1Split (line 552) | void Parse1Split(benchmark::State& state,
    function Parse_Split_NFA (line 559) | void Parse_Split_NFA(benchmark::State& state)         { Parse1Split(st...
    function Parse_Split_OnePass (line 560) | void Parse_Split_OnePass(benchmark::State& state)     { Parse1Split(st...
    function Parse_Split_PCRE (line 561) | void Parse_Split_PCRE(benchmark::State& state)        { Parse1Split(st...
    function Parse_Split_RE2 (line 562) | void Parse_Split_RE2(benchmark::State& state)         { Parse1Split(st...
    function Parse_Split_BitState (line 563) | void Parse_Split_BitState(benchmark::State& state)    { Parse1Split(st...
    function Parse_CachedSplit_NFA (line 573) | void Parse_CachedSplit_NFA(benchmark::State& state)         { Parse1Sp...
    function Parse_CachedSplit_OnePass (line 574) | void Parse_CachedSplit_OnePass(benchmark::State& state)     { Parse1Sp...
    function Parse_CachedSplit_PCRE (line 575) | void Parse_CachedSplit_PCRE(benchmark::State& state)        { Parse1Sp...
    function Parse_CachedSplit_RE2 (line 576) | void Parse_CachedSplit_RE2(benchmark::State& state)         { Parse1Sp...
    function Parse_CachedSplit_BitState (line 577) | void Parse_CachedSplit_BitState(benchmark::State& state)    { Parse1Sp...
    function Parse1SplitHard (line 589) | void Parse1SplitHard(benchmark::State& state,
    function Parse_SplitHard_NFA (line 596) | void Parse_SplitHard_NFA(benchmark::State& state)         { Parse1Spli...
    function Parse_SplitHard_PCRE (line 597) | void Parse_SplitHard_PCRE(benchmark::State& state)        { Parse1Spli...
    function Parse_SplitHard_RE2 (line 598) | void Parse_SplitHard_RE2(benchmark::State& state)         { Parse1Spli...
    function Parse_SplitHard_BitState (line 599) | void Parse_SplitHard_BitState(benchmark::State& state)    { Parse1Spli...
    function Parse_CachedSplitHard_NFA (line 608) | void Parse_CachedSplitHard_NFA(benchmark::State& state)       { Parse1...
    function Parse_CachedSplitHard_PCRE (line 609) | void Parse_CachedSplitHard_PCRE(benchmark::State& state)      { Parse1...
    function Parse_CachedSplitHard_RE2 (line 610) | void Parse_CachedSplitHard_RE2(benchmark::State& state)       { Parse1...
    function Parse_CachedSplitHard_BitState (line 611) | void Parse_CachedSplitHard_BitState(benchmark::State& state)  { Parse1...
    function Parse_CachedSplitHard_Backtrack (line 612) | void Parse_CachedSplitHard_Backtrack(benchmark::State& state) { Parse1...
    function Parse1SplitBig1 (line 624) | void Parse1SplitBig1(benchmark::State& state,
    function Parse_CachedSplitBig1_PCRE (line 634) | void Parse_CachedSplitBig1_PCRE(benchmark::State& state)      { Parse1...
    function Parse_CachedSplitBig1_RE2 (line 635) | void Parse_CachedSplitBig1_RE2(benchmark::State& state)       { Parse1...
    function Parse1SplitBig2 (line 644) | void Parse1SplitBig2(benchmark::State& state,
    function Parse_CachedSplitBig2_PCRE (line 654) | void Parse_CachedSplitBig2_PCRE(benchmark::State& state)      { Parse1...
    function Parse_CachedSplitBig2_RE2 (line 655) | void Parse_CachedSplitBig2_RE2(benchmark::State& state)       { Parse1...
    function ParseRegexp (line 665) | void ParseRegexp(benchmark::State& state, const std::string& regexp) {
    function SimplifyRegexp (line 673) | void SimplifyRegexp(benchmark::State& state, const std::string& regexp) {
    function NullWalkRegexp (line 684) | void NullWalkRegexp(benchmark::State& state, const std::string& regexp) {
    function SimplifyCompileRegexp (line 693) | void SimplifyCompileRegexp(benchmark::State& state, const std::string&...
    function CompileRegexp (line 707) | void CompileRegexp(benchmark::State& state, const std::string& regexp) {
    function CompileToProg (line 718) | void CompileToProg(benchmark::State& state, const std::string& regexp) {
    function CompileByteMap (line 729) | void CompileByteMap(benchmark::State& state, const std::string& regexp) {
    function CompilePCRE (line 741) | void CompilePCRE(benchmark::State& state, const std::string& regexp) {
    function CompileRE2 (line 748) | void CompileRE2(benchmark::State& state, const std::string& regexp) {
    function RunBuild (line 755) | void RunBuild(benchmark::State& state, const std::string& regexp,
    function BM_PCRE_Compile (line 768) | void BM_PCRE_Compile(benchmark::State& state)             { RunBuild(s...
    function BM_Regexp_Parse (line 769) | void BM_Regexp_Parse(benchmark::State& state)             { RunBuild(s...
    function BM_Regexp_Simplify (line 770) | void BM_Regexp_Simplify(benchmark::State& state)          { RunBuild(s...
    function BM_CompileToProg (line 771) | void BM_CompileToProg(benchmark::State& state)            { RunBuild(s...
    function BM_CompileByteMap (line 772) | void BM_CompileByteMap(benchmark::State& state)           { RunBuild(s...
    function BM_Regexp_Compile (line 773) | void BM_Regexp_Compile(benchmark::State& state)           { RunBuild(s...
    function BM_Regexp_SimplifyCompile (line 774) | void BM_Regexp_SimplifyCompile(benchmark::State& state)   { RunBuild(s...
    function BM_Regexp_NullWalk (line 775) | void BM_Regexp_NullWalk(benchmark::State& state)          { RunBuild(s...
    function BM_RE2_Compile (line 776) | void BM_RE2_Compile(benchmark::State& state)              { RunBuild(s...
    function SearchPhone (line 792) | void SearchPhone(benchmark::State& state, ParseImpl* search) {
    function SearchPhone_CachedPCRE (line 799) | void SearchPhone_CachedPCRE(benchmark::State& state) {
    function SearchPhone_CachedRE2 (line 803) | void SearchPhone_CachedRE2(benchmark::State& state) {
    function SearchDFA (line 865) | void SearchDFA(benchmark::State& state, const char* regexp,
    function SearchNFA (line 883) | void SearchNFA(benchmark::State& state, const char* regexp,
    function SearchOnePass (line 899) | void SearchOnePass(benchmark::State& state, const char* regexp,
    function SearchBitState (line 916) | void SearchBitState(benchmark::State& state, const char* regexp,
    function SearchPCRE (line 933) | void SearchPCRE(benchmark::State& state, const char* regexp,
    function SearchRE2 (line 947) | void SearchRE2(benchmark::State& state, const char* regexp,
    function Prog (line 965) | Prog* GetCachedProg(const char* regexp) {
    function PCRE (line 983) | PCRE* GetCachedPCRE(const char* regexp) {
    function RE2 (line 996) | RE2* GetCachedRE2(const char* regexp) {
    function SearchCachedDFA (line 1009) | void SearchCachedDFA(benchmark::State& state, const char* regexp,
    function SearchCachedNFA (line 1022) | void SearchCachedNFA(benchmark::State& state, const char* regexp,
    function SearchCachedOnePass (line 1033) | void SearchCachedOnePass(benchmark::State& state, const char* regexp,
    function SearchCachedBitState (line 1045) | void SearchCachedBitState(benchmark::State& state, const char* regexp,
    function SearchCachedPCRE (line 1057) | void SearchCachedPCRE(benchmark::State& state, const char* regexp,
    function SearchCachedRE2 (line 1070) | void SearchCachedRE2(benchmark::State& state, const char* regexp,
    function Parse3NFA (line 1086) | void Parse3NFA(benchmark::State& state, const char* regexp,
    function Parse3OnePass (line 1101) | void Parse3OnePass(benchmark::State& state, const char* regexp,
    function Parse3BitState (line 1117) | void Parse3BitState(benchmark::State& state, const char* regexp,
    function Parse3Backtrack (line 1133) | void Parse3Backtrack(benchmark::State& state, const char* regexp,
    function Parse3PCRE (line 1148) | void Parse3PCRE(benchmark::State& state, const char* regexp,
    function Parse3RE2 (line 1158) | void Parse3RE2(benchmark::State& state, const char* regexp,
    function Parse3CachedNFA (line 1168) | void Parse3CachedNFA(benchmark::State& state, const char* regexp,
    function Parse3CachedOnePass (line 1178) | void Parse3CachedOnePass(benchmark::State& state, const char* regexp,
    function Parse3CachedBitState (line 1189) | void Parse3CachedBitState(benchmark::State& state, const char* regexp,
    function Parse3CachedBacktrack (line 1200) | void Parse3CachedBacktrack(benchmark::State& state, const char* regexp,
    function Parse3CachedPCRE (line 1210) | void Parse3CachedPCRE(benchmark::State& state, const char* regexp,
    function Parse3CachedRE2 (line 1219) | void Parse3CachedRE2(benchmark::State& state, const char* regexp,
    function Parse1NFA (line 1231) | void Parse1NFA(benchmark::State& state, const char* regexp,
    function Parse1OnePass (line 1246) | void Parse1OnePass(benchmark::State& state, const char* regexp,
    function Parse1BitState (line 1262) | void Parse1BitState(benchmark::State& state, const char* regexp,
    function Parse1PCRE (line 1278) | void Parse1PCRE(benchmark::State& state, const char* regexp,
    function Parse1RE2 (line 1288) | void Parse1RE2(benchmark::State& state, const char* regexp,
    function Parse1CachedNFA (line 1298) | void Parse1CachedNFA(benchmark::State& state, const char* regexp,
    function Parse1CachedOnePass (line 1308) | void Parse1CachedOnePass(benchmark::State& state, const char* regexp,
    function Parse1CachedBitState (line 1319) | void Parse1CachedBitState(benchmark::State& state, const char* regexp,
    function Parse1CachedBacktrack (line 1330) | void Parse1CachedBacktrack(benchmark::State& state, const char* regexp,
    function Parse1CachedPCRE (line 1340) | void Parse1CachedPCRE(benchmark::State& state, const char* regexp,
    function Parse1CachedRE2 (line 1349) | void Parse1CachedRE2(benchmark::State& state, const char* regexp,
    function SearchParse2CachedPCRE (line 1358) | void SearchParse2CachedPCRE(benchmark::State& state, const char* regexp,
    function SearchParse2CachedRE2 (line 1367) | void SearchParse2CachedRE2(benchmark::State& state, const char* regexp,
    function SearchParse1CachedPCRE (line 1376) | void SearchParse1CachedPCRE(benchmark::State& state, const char* regexp,
    function SearchParse1CachedRE2 (line 1385) | void SearchParse1CachedRE2(benchmark::State& state, const char* regexp,
    function EmptyPartialMatchPCRE (line 1394) | void EmptyPartialMatchPCRE(benchmark::State& state) {
    function EmptyPartialMatchRE2 (line 1401) | void EmptyPartialMatchRE2(benchmark::State& state) {
    function SimplePartialMatchPCRE (line 1412) | void SimplePartialMatchPCRE(benchmark::State& state) {
    function SimplePartialMatchRE2 (line 1419) | void SimplePartialMatchRE2(benchmark::State& state) {
    function HTTPPartialMatchPCRE (line 1434) | void HTTPPartialMatchPCRE(benchmark::State& state) {
    function HTTPPartialMatchRE2 (line 1442) | void HTTPPartialMatchRE2(benchmark::State& state) {
    function SmallHTTPPartialMatchPCRE (line 1458) | void SmallHTTPPartialMatchPCRE(benchmark::State& state) {
    function SmallHTTPPartialMatchRE2 (line 1466) | void SmallHTTPPartialMatchRE2(benchmark::State& state) {
    function DotMatchPCRE (line 1479) | void DotMatchPCRE(benchmark::State& state) {
    function DotMatchRE2 (line 1487) | void DotMatchRE2(benchmark::State& state) {
    function ASCIIMatchPCRE (line 1500) | void ASCIIMatchPCRE(benchmark::State& state) {
    function ASCIIMatchRE2 (line 1508) | void ASCIIMatchRE2(benchmark::State& state) {
    function FullMatchPCRE (line 1521) | void FullMatchPCRE(benchmark::State& state, const char *regexp) {
    function FullMatchRE2 (line 1531) | void FullMatchRE2(benchmark::State& state, const char *regexp) {
    function FullMatch_DotStar_CachedPCRE (line 1541) | void FullMatch_DotStar_CachedPCRE(benchmark::State& state) {
    function FullMatch_DotStar_CachedRE2 (line 1544) | void FullMatch_DotStar_CachedRE2(benchmark::State& state) {
    function FullMatch_DotStarDollar_CachedPCRE (line 1548) | void FullMatch_DotStarDollar_CachedPCRE(benchmark::State& state) {
    function FullMatch_DotStarDollar_CachedRE2 (line 1551) | void FullMatch_DotStarDollar_CachedRE2(benchmark::State& state) {
    function FullMatch_DotStarCapture_CachedPCRE (line 1555) | void FullMatch_DotStarCapture_CachedPCRE(benchmark::State& state) {
    function FullMatch_DotStarCapture_CachedRE2 (line 1558) | void FullMatch_DotStarCapture_CachedRE2(benchmark::State& state) {
    function PossibleMatchRangeCommon (line 1577) | void PossibleMatchRangeCommon(benchmark::State& state, const char* reg...
    function PossibleMatchRange_Trivial (line 1587) | void PossibleMatchRange_Trivial(benchmark::State& state) {
    function PossibleMatchRange_Complex (line 1590) | void PossibleMatchRange_Complex(benchmark::State& state) {
    function PossibleMatchRange_Prefix (line 1593) | void PossibleMatchRange_Prefix(benchmark::State& state) {
    function PossibleMatchRange_NoProg (line 1596) | void PossibleMatchRange_NoProg(benchmark::State& state) {

FILE: re2/testing/regexp_generator.cc
  type re2 (line 44) | namespace re2 {
    function CountArgs (line 89) | static int CountArgs(const std::string& s) {
    function Explode (line 249) | std::vector<std::string> Explode(absl::string_view s) {
    function Split (line 264) | std::vector<std::string> Split(absl::string_view sep, absl::string_vie...

FILE: re2/testing/regexp_generator.h
  function namespace (line 19) | namespace re2 {

FILE: re2/testing/regexp_test.cc
  type re2 (line 17) | namespace re2 {
    function TEST (line 20) | TEST(Regexp, BigRef) {
    function TEST (line 33) | TEST(Regexp, BigConcat) {
    function TEST (line 48) | TEST(Regexp, NamedCaptures) {
    function TEST (line 67) | TEST(Regexp, CaptureNames) {

FILE: re2/testing/required_prefix_test.cc
  type re2 (line 14) | namespace re2 {
    type PrefixTest (line 16) | struct PrefixTest {
    function TEST (line 48) | TEST(RequiredPrefix, SimpleTests) {
    function TEST (line 110) | TEST(RequiredPrefixForAccel, SimpleTests) {
    function TEST (line 136) | TEST(RequiredPrefixForAccel, CaseFoldingForKAndS) {
    function TEST (line 175) | TEST(PrefixAccel, SimpleTests) {

FILE: re2/testing/search_test.cc
  type re2 (line 20) | namespace re2 {
    type RegexpTest (line 22) | struct RegexpTest {
    function TEST (line 319) | TEST(Regexp, SearchTests) {

FILE: re2/testing/set_test.cc
  type re2 (line 15) | namespace re2 {
    function TEST (line 17) | TEST(Set, Unanchored) {
    function TEST (line 49) | TEST(Set, UnanchoredFactored) {
    function TEST (line 81) | TEST(Set, UnanchoredDollar) {
    function TEST (line 99) | TEST(Set, UnanchoredWordBoundary) {
    function TEST (line 122) | TEST(Set, Anchored) {
    function TEST (line 155) | TEST(Set, EmptyUnanchored) {
    function TEST (line 171) | TEST(Set, EmptyAnchored) {
    function TEST (line 187) | TEST(Set, Prefix) {
    function TEST (line 210) | TEST(Set, MoveSemantics) {

FILE: re2/testing/simplify_test.cc
  type re2 (line 14) | namespace re2 {
    type Test (line 16) | struct Test {
    function TEST (line 263) | TEST(TestSimplify, SimpleRegexps) {

FILE: re2/testing/string_generator.cc
  type re2 (line 21) | namespace re2 {
    function DeBruijnString (line 117) | std::string DeBruijnString(int n) {

FILE: re2/testing/string_generator.h
  function namespace (line 20) | namespace re2 {

FILE: re2/testing/string_generator_test.cc
  type re2 (line 19) | namespace re2 {
    function IntegerPower (line 22) | static int64_t IntegerPower(int i, int e) {
    function RunTest (line 38) | static void RunTest(int len, const std::string& alphabet, bool donull) {
    function TEST (line 86) | TEST(StringGenerator, NoLength) {
    function TEST (line 90) | TEST(StringGenerator, NoLengthNoAlphabet) {
    function TEST (line 94) | TEST(StringGenerator, NoAlphabet) {
    function TEST (line 98) | TEST(StringGenerator, Simple) {
    function TEST (line 102) | TEST(StringGenerator, UTF8) {
    function TEST (line 106) | TEST(StringGenerator, GenNULL) {

FILE: re2/testing/tester.cc
  function Engines (line 65) | static uint32_t Engines() {
  type TestInstance::Result (line 94) | struct TestInstance::Result {
    method Result (line 95) | Result()
    method ClearSubmatch (line 104) | void ClearSubmatch() {
  function FormatCapture (line 121) | static std::string FormatCapture(absl::string_view text,
  function NonASCII (line 131) | static bool NonASCII(absl::string_view text) {
  function FormatKind (line 139) | static std::string FormatKind(Prog::MatchKind kind) {
  function FormatAnchor (line 154) | static std::string FormatAnchor(Prog::Anchor anchor) {
  type ParseMode (line 164) | struct ParseMode {
  function FormatMode (line 182) | static std::string FormatMode(Regexp::ParseFlags flags) {
  function ResultOkay (line 503) | static bool ResultOkay(const Result& r, const Result& correct) {
  function TestRegexpOnText (line 684) | bool TestRegexpOnText(absl::string_view regexp,

FILE: re2/testing/tester.h
  function namespace (line 19) | namespace re2 {

FILE: re2/tostring.cc
  type re2 (line 18) | namespace re2 {
    class ToStringWalker (line 37) | class ToStringWalker : public Regexp::Walker<int> {
      method ToStringWalker (line 39) | explicit ToStringWalker(std::string* t) : t_(t) {}
      method ShortVisit (line 44) | virtual int ShortVisit(Regexp* re, int parent_arg) {
      method ToStringWalker (line 51) | ToStringWalker(const ToStringWalker&) = delete;
      method ToStringWalker (line 52) | ToStringWalker& operator=(const ToStringWalker&) = delete;
    function AppendLiteral (line 129) | static void AppendLiteral(std::string *t, Rune r, bool foldcase) {
    function AppendCCChar (line 306) | static void AppendCCChar(std::string* t, Rune r) {
    function AppendCCRange (line 341) | static void AppendCCRange(std::string* t, Rune lo, Rune hi) {

FILE: re2/unicode.py
  class Error (line 22) | class Error(Exception):
  class InputError (line 26) | class InputError(Error):
  function _UInt (line 30) | def _UInt(s):
  function _URange (line 52) | def _URange(s):
  function _ParseContinue (line 78) | def _ParseContinue(s):
  function ReadUnicodeTable (line 105) | def ReadUnicodeTable(filename, nfields, doline):
  function CaseGroups (line 206) | def CaseGroups(unicode_dir=_UNICODE_DIR):
  function Scripts (line 240) | def Scripts(unicode_dir=_UNICODE_DIR):
  function Categories (line 261) | def Categories(unicode_dir=_UNICODE_DIR):

FILE: re2/unicode_casefold.cc
  type re2 (line 7) | namespace re2 {

FILE: re2/unicode_casefold.h
  function namespace (line 46) | namespace re2 {

FILE: re2/unicode_groups.cc
  type re2 (line 7) | namespace re2 {

FILE: re2/unicode_groups.h
  function namespace (line 25) | namespace re2 {

FILE: re2/walker-inl.h
  function namespace (line 23) | namespace re2 {

FILE: testinstall.cc
  function main (line 9) | int main() {

FILE: util/malloc_counter.h
  function namespace (line 8) | namespace testing {

FILE: util/pcre.cc
  function ABSL_FLAG (line 36) | ABSL_FLAG(int, regexp_stack_limit, 256 << 10,
  function parse_double_float (line 895) | static bool parse_double_float(const char* str, size_t n, bool isfloat,

FILE: util/pcre.h
  function namespace (line 168) | namespace re2 {
  type pcre (line 172) | struct pcre
  function namespace (line 173) | namespace re2 {
  function namespace (line 188) | namespace re2 {
  function class (line 511) | class PCRE_Options {
  function class (line 558) | class PCRE::Arg {
  function PCRE (line 639) | inline PCRE::Arg::Arg() : arg_(NULL), parser_(parse_null) { }

FILE: util/rune.cc
  type re2 (line 20) | namespace re2 {
    function chartorune (line 50) | int
    function runetochar (line 126) | int
    function runelen (line 183) | int
    function fullrune (line 191) | int
    function utflen (line 211) | int

FILE: util/strutil.cc
  type re2 (line 7) | namespace re2 {
    function PrefixSuccessor (line 9) | void PrefixSuccessor(std::string* prefix) {

FILE: util/strutil.h
  function namespace (line 10) | namespace re2 {

FILE: util/utf.h
  function namespace (line 23) | namespace re2 {
Condensed preview — 134 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (1,411K chars).
[
  {
    "path": ".bazelrc",
    "chars": 689,
    "preview": "# Copyright 2022 The RE2 Authors.  All Rights Reserved.\n# Use of this source code is governed by a BSD-style\n# license t"
  },
  {
    "path": ".bcr/metadata.template.json",
    "chars": 311,
    "preview": "{\n  \"homepage\": \"https://github.com/google/re2\",\n  \"maintainers\": [\n      {\n          \"email\": \"rsc@google.com\",\n       "
  },
  {
    "path": ".bcr/presubmit.yml",
    "chars": 1004,
    "preview": "matrix:\n  platform:\n  - rockylinux8\n  - debian10\n  - ubuntu2004\n  - macos\n  bazel:\n  - 7.x\n  - 8.x\n\ntasks:\n  unix_build:"
  },
  {
    "path": ".bcr/source.template.json",
    "chars": 147,
    "preview": "{\n  \"integrity\": \"\",\n  \"strip_prefix\": \"{REPO}-{VERSION}\",\n  \"url\": \"https://github.com/{OWNER}/{REPO}/releases/download"
  },
  {
    "path": ".github/bazel.sh",
    "chars": 504,
    "preview": "#!/bin/bash\nset -eux\n\n# Disable MSYS/MSYS2 path conversion, which interferes with Bazel.\nexport MSYS_NO_PATHCONV='1'\nexp"
  },
  {
    "path": ".github/cmake.sh",
    "chars": 294,
    "preview": "#!/bin/bash\nset -eux\n\nfor CMAKE_BUILD_TYPE in Debug Release\ndo\n  cmake . -D CMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} -D RE2_"
  },
  {
    "path": ".github/workflows/ci-bazel.yml",
    "chars": 994,
    "preview": "name: CI (Bazel)\non:\n  pull_request:\n    branches: [main]\n  push:\n    branches: [main, rsc-testing]\npermissions:\n  conte"
  },
  {
    "path": ".github/workflows/ci-cmake.yml",
    "chars": 1672,
    "preview": "name: CI (CMake)\non:\n  pull_request:\n    branches: [main]\n  push:\n    branches: [main, rsc-testing]\npermissions:\n  conte"
  },
  {
    "path": ".github/workflows/ci.yml",
    "chars": 2392,
    "preview": "name: CI\non:\n  pull_request:\n    branches: [main]\n  push:\n    branches: [main, rsc-testing]\npermissions:\n  contents: rea"
  },
  {
    "path": ".github/workflows/pages.yml",
    "chars": 1046,
    "preview": "name: Pages\non:\n  workflow_dispatch:\npermissions:\n  contents: read\njobs:\n  build:\n    runs-on: ubuntu-latest\n    contain"
  },
  {
    "path": ".github/workflows/python.yml",
    "chars": 9609,
    "preview": "name: Python\non:\n  workflow_dispatch:\n    inputs:\n      build:\n        required: true\n        type: number\n      force-s"
  },
  {
    "path": ".github/workflows/release-bazel.yml",
    "chars": 1497,
    "preview": "name: Release (Bazel)\non:\n  # Allow manual triggering from GH UI\n  workflow_dispatch:\n    inputs:\n      tag_name:\n      "
  },
  {
    "path": ".github/workflows/release.yml",
    "chars": 1494,
    "preview": "name: Release\non:\n  push:\n    tags: ['2[0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]'] # yyyy-mm-dd\npermissions:\n  contents: rea"
  },
  {
    "path": ".gitignore",
    "chars": 47,
    "preview": "*.pyc\n*.orig\ncore\nobj/\nbenchlog.*\nuser.bazelrc\n"
  },
  {
    "path": "BUILD.bazel",
    "chars": 12011,
    "preview": "# Copyright 2009 The RE2 Authors.  All Rights Reserved.\n# Use of this source code is governed by a BSD-style\n# license t"
  },
  {
    "path": "CMakeLists.txt",
    "chars": 8888,
    "preview": "# Copyright 2015 The RE2 Authors.  All Rights Reserved.\n# Use of this source code is governed by a BSD-style\n# license t"
  },
  {
    "path": "CONTRIBUTING.md",
    "chars": 79,
    "preview": "See the [Contribute](https://github.com/google/re2/wiki/Contribute) wiki page.\n"
  },
  {
    "path": "LICENSE",
    "chars": 1558,
    "preview": "// Copyright (c) 2009 The RE2 Authors. All rights reserved.\n//\n// Redistribution and use in source and binary forms, wit"
  },
  {
    "path": "MODULE.bazel",
    "chars": 1227,
    "preview": "# Copyright 2009 The RE2 Authors.  All Rights Reserved.\n# Use of this source code is governed by a BSD-style\n# license t"
  },
  {
    "path": "Makefile",
    "chars": 12365,
    "preview": "# Copyright 2009 The RE2 Authors.  All Rights Reserved.\n# Use of this source code is governed by a BSD-style\n# license t"
  },
  {
    "path": "README.md",
    "chars": 11410,
    "preview": "# RE2, a regular expression library\n\nRE2 is an efficient, principled regular expression library\nthat has been used in pr"
  },
  {
    "path": "SECURITY.md",
    "chars": 293,
    "preview": "To report a security issue, please use https://g.co/vulnz. We use\nhttps://g.co/vulnz for our intake, and do coordination"
  },
  {
    "path": "WORKSPACE.bazel",
    "chars": 260,
    "preview": "# Copyright 2009 The RE2 Authors.  All Rights Reserved.\n# Use of this source code is governed by a BSD-style\n# license t"
  },
  {
    "path": "WORKSPACE.bzlmod",
    "chars": 260,
    "preview": "# Copyright 2009 The RE2 Authors.  All Rights Reserved.\n# Use of this source code is governed by a BSD-style\n# license t"
  },
  {
    "path": "app/BUILD.bazel",
    "chars": 565,
    "preview": "# Copyright 2009 The RE2 Authors.  All Rights Reserved.\n# Use of this source code is governed by a BSD-style\n# license t"
  },
  {
    "path": "app/_re2.cc",
    "chars": 2537,
    "preview": "// Copyright 2022 The RE2 Authors.  All Rights Reserved.\n// Use of this source code is governed by a BSD-style\n// licens"
  },
  {
    "path": "app/_re2.d.ts",
    "chars": 923,
    "preview": "// Copyright 2022 The RE2 Authors.  All Rights Reserved.\n// Use of this source code is governed by a BSD-style\n// licens"
  },
  {
    "path": "app/app.ts",
    "chars": 2549,
    "preview": "// Copyright 2022 The RE2 Authors.  All Rights Reserved.\n// Use of this source code is governed by a BSD-style\n// licens"
  },
  {
    "path": "app/build.sh",
    "chars": 776,
    "preview": "#!/bin/bash\nset -eux\n\nSRCDIR=$(readlink --canonicalize $(dirname $0))\nDSTDIR=$(mktemp --directory --tmpdir $(basename $0"
  },
  {
    "path": "app/index.html",
    "chars": 204,
    "preview": "<!DOCTYPE html>\n<meta charset=\"utf-8\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n<style>:root"
  },
  {
    "path": "app/package.json",
    "chars": 291,
    "preview": "{\n  \"dependencies\": {\n    \"lit\": \"*\"\n  },\n  \"devDependencies\": {\n    \"@rollup/plugin-node-resolve\": \"*\",\n    \"@rollup/pl"
  },
  {
    "path": "app/rollup.config.js",
    "chars": 743,
    "preview": "// Copyright 2022 The RE2 Authors.  All Rights Reserved.\n// Use of this source code is governed by a BSD-style\n// licens"
  },
  {
    "path": "app/tsconfig.json",
    "chars": 397,
    "preview": "{\n  \"compilerOptions\": {\n    \"target\": \"esnext\",\n    \"module\": \"esnext\",\n    \"moduleResolution\": \"node\",\n    \"noEmitOnEr"
  },
  {
    "path": "benchlog/benchplot.py",
    "chars": 2726,
    "preview": "#!/usr/bin/env python\n\nimport argparse     # for ArgumentParser\nimport subprocess   # for Popen\nimport tempfile     # fo"
  },
  {
    "path": "benchlog/mktable",
    "chars": 3480,
    "preview": "#!/usr/bin/perl\n# XXX\n\nsub table() {\n\tmy ($name) = @_;\n\tprint <<'EOF';\n<table border=0>\n<tr><th>System</th><th>PCRE</th>"
  },
  {
    "path": "doc/mksyntaxgo",
    "chars": 1221,
    "preview": "#!/bin/sh\n\nset -e\nout=$GOROOT/src/regexp/syntax/doc.go\ncp syntax.txt $out\nsam -d $out <<'!'\n,x g/NOT SUPPORTED/d\n/^Unico"
  },
  {
    "path": "doc/mksyntaxhtml",
    "chars": 1125,
    "preview": "#!/bin/sh\n\ncp syntax.txt syntax.html\nsam -d syntax.html <<'!'\n,s/\\&/\\&amp;/g\n,s/</\\&lt;/g\n,s/>/\\&gt;/g\n,s!== (([^()]|\\(["
  },
  {
    "path": "doc/mksyntaxwiki",
    "chars": 1042,
    "preview": "#!/bin/sh\n\ncp syntax.txt syntax.wiki\nsam -d syntax.wiki <<'!'\n,s!`!`````!g\n,s!== (([^()]|\\([^()]*\\))*)!≡ `\\1`!g\n,s!«!`!g"
  },
  {
    "path": "doc/syntax.html",
    "chars": 32752,
    "preview": "<html>\n<!-- AUTOMATICALLY GENERATED by mksyntaxhtml -->\n<head>\n<meta http-equiv=\"Content-Type\" content=\"text/html; chars"
  },
  {
    "path": "doc/syntax.txt",
    "chars": 11709,
    "preview": "RE2 regular expression syntax reference\n-------------------------­-------­-----\n\nSingle characters:\n.\tany character, pos"
  },
  {
    "path": "lib/git/commit-msg.hook",
    "chars": 2329,
    "preview": "#!/bin/sh\n# From Gerrit Code Review 2.2.1\n#\n# Part of Gerrit Code Review (http://code.google.com/p/gerrit/)\n#\n# Copyrigh"
  },
  {
    "path": "libre2.symbols",
    "chars": 258,
    "preview": "{\n\tglobal:\n\t\t# re2::RE2*\n\t\t_ZN3re23RE2*;\n\t\t_ZNK3re23RE2*;\n\t\t# re2::operator<<*\n\t\t_ZN3re2ls*;\n\t\t# re2::FilteredRE2*\n\t\t_ZN"
  },
  {
    "path": "libre2.symbols.darwin",
    "chars": 248,
    "preview": "# Linker doesn't like these unmangled:\n# re2::RE2*\n__ZN3re23RE2*\n__ZNK3re23RE2*\n# re2::operator<<*\n__ZN3re2ls*\n# re2::Fi"
  },
  {
    "path": "python/BUILD.bazel",
    "chars": 1738,
    "preview": "# Copyright 2009 The RE2 Authors.  All Rights Reserved.\n# Use of this source code is governed by a BSD-style\n# license t"
  },
  {
    "path": "python/README",
    "chars": 72,
    "preview": "Building requires Python 3 and pybind11 to be installed on your system.\n"
  },
  {
    "path": "python/_re2.cc",
    "chars": 11828,
    "preview": "// Copyright 2019 The RE2 Authors.  All Rights Reserved.\n// Use of this source code is governed by a BSD-style\n// licens"
  },
  {
    "path": "python/re2.py",
    "chars": 17671,
    "preview": "# Copyright 2019 The RE2 Authors.  All Rights Reserved.\n# Use of this source code is governed by a BSD-style\n# license t"
  },
  {
    "path": "python/re2_test.py",
    "chars": 19317,
    "preview": "# Copyright 2019 The RE2 Authors.  All Rights Reserved.\n# Use of this source code is governed by a BSD-style\n# license t"
  },
  {
    "path": "python/setup.py",
    "chars": 5730,
    "preview": "# Copyright 2019 The RE2 Authors.  All Rights Reserved.\n# Use of this source code is governed by a BSD-style\n# license t"
  },
  {
    "path": "python/toolchains/generate.py",
    "chars": 2417,
    "preview": "# Copyright 2019 The RE2 Authors.  All Rights Reserved.\n# Use of this source code is governed by a BSD-style\n# license t"
  },
  {
    "path": "re2/bitmap256.cc",
    "chars": 1001,
    "preview": "// Copyright 2023 The RE2 Authors.  All Rights Reserved.\n// Use of this source code is governed by a BSD-style\n// licens"
  },
  {
    "path": "re2/bitmap256.h",
    "chars": 1911,
    "preview": "// Copyright 2016 The RE2 Authors.  All Rights Reserved.\n// Use of this source code is governed by a BSD-style\n// licens"
  },
  {
    "path": "re2/bitstate.cc",
    "chars": 11905,
    "preview": "// Copyright 2008 The RE2 Authors.  All Rights Reserved.\n// Use of this source code is governed by a BSD-style\n// licens"
  },
  {
    "path": "re2/compile.cc",
    "chars": 38927,
    "preview": "// Copyright 2007 The RE2 Authors.  All Rights Reserved.\n// Use of this source code is governed by a BSD-style\n// licens"
  },
  {
    "path": "re2/dfa.cc",
    "chars": 75179,
    "preview": "// Copyright 2008 The RE2 Authors.  All Rights Reserved.\n// Use of this source code is governed by a BSD-style\n// licens"
  },
  {
    "path": "re2/filtered_re2.cc",
    "chars": 3987,
    "preview": "// Copyright 2009 The RE2 Authors.  All Rights Reserved.\n// Use of this source code is governed by a BSD-style\n// licens"
  },
  {
    "path": "re2/filtered_re2.h",
    "chars": 4281,
    "preview": "// Copyright 2009 The RE2 Authors.  All Rights Reserved.\n// Use of this source code is governed by a BSD-style\n// licens"
  },
  {
    "path": "re2/fuzzing/re2_fuzzer.cc",
    "chars": 9549,
    "preview": "// Copyright 2016 The RE2 Authors.  All Rights Reserved.\n// Use of this source code is governed by a BSD-style\n// licens"
  },
  {
    "path": "re2/make_perl_groups.pl",
    "chars": 2448,
    "preview": "#!/usr/bin/perl\n# Copyright 2008 The RE2 Authors.  All Rights Reserved.\n# Use of this source code is governed by a BSD-s"
  },
  {
    "path": "re2/make_unicode_casefold.py",
    "chars": 3741,
    "preview": "#!/usr/bin/python3\n# coding=utf-8\n#\n# Copyright 2008 The RE2 Authors.  All Rights Reserved.\n# Use of this source code is"
  },
  {
    "path": "re2/make_unicode_groups.py",
    "chars": 3033,
    "preview": "#!/usr/bin/python3\n# Copyright 2008 The RE2 Authors.  All Rights Reserved.\n# Use of this source code is governed by a BS"
  },
  {
    "path": "re2/mimics_pcre.cc",
    "chars": 6319,
    "preview": "// Copyright 2008 The RE2 Authors.  All Rights Reserved.\n// Use of this source code is governed by a BSD-style\n// licens"
  },
  {
    "path": "re2/nfa.cc",
    "chars": 21063,
    "preview": "// Copyright 2006-2007 The RE2 Authors.  All Rights Reserved.\n// Use of this source code is governed by a BSD-style\n// l"
  },
  {
    "path": "re2/onepass.cc",
    "chars": 23077,
    "preview": "// Copyright 2008 The RE2 Authors.  All Rights Reserved.\n// Use of this source code is governed by a BSD-style\n// licens"
  },
  {
    "path": "re2/parse.cc",
    "chars": 78578,
    "preview": "// Copyright 2006 The RE2 Authors.  All Rights Reserved.\n// Use of this source code is governed by a BSD-style\n// licens"
  },
  {
    "path": "re2/perl_groups.cc",
    "chars": 3087,
    "preview": "// GENERATED BY make_perl_groups.pl; DO NOT EDIT.\n// make_perl_groups.pl >perl_groups.cc\n\n#include \"re2/unicode_groups.h"
  },
  {
    "path": "re2/pod_array.h",
    "chars": 1052,
    "preview": "// Copyright 2018 The RE2 Authors.  All Rights Reserved.\n// Use of this source code is governed by a BSD-style\n// licens"
  },
  {
    "path": "re2/prefilter.cc",
    "chars": 17725,
    "preview": "// Copyright 2009 The RE2 Authors.  All Rights Reserved.\n// Use of this source code is governed by a BSD-style\n// licens"
  },
  {
    "path": "re2/prefilter.h",
    "chars": 4929,
    "preview": "// Copyright 2009 The RE2 Authors.  All Rights Reserved.\n// Use of this source code is governed by a BSD-style\n// licens"
  },
  {
    "path": "re2/prefilter_tree.cc",
    "chars": 11920,
    "preview": "// Copyright 2009 The RE2 Authors.  All Rights Reserved.\n// Use of this source code is governed by a BSD-style\n// licens"
  },
  {
    "path": "re2/prefilter_tree.h",
    "chars": 5543,
    "preview": "// Copyright 2009 The RE2 Authors.  All Rights Reserved.\n// Use of this source code is governed by a BSD-style\n// licens"
  },
  {
    "path": "re2/prog.cc",
    "chars": 37837,
    "preview": "// Copyright 2007 The RE2 Authors.  All Rights Reserved.\n// Use of this source code is governed by a BSD-style\n// licens"
  },
  {
    "path": "re2/prog.h",
    "chars": 19630,
    "preview": "// Copyright 2007 The RE2 Authors.  All Rights Reserved.\n// Use of this source code is governed by a BSD-style\n// licens"
  },
  {
    "path": "re2/re2.cc",
    "chars": 40207,
    "preview": "// Copyright 2003-2009 The RE2 Authors.  All Rights Reserved.\n// Use of this source code is governed by a BSD-style\n// l"
  },
  {
    "path": "re2/re2.h",
    "chars": 42153,
    "preview": "// Copyright 2003-2009 The RE2 Authors.  All Rights Reserved.\n// Use of this source code is governed by a BSD-style\n// l"
  },
  {
    "path": "re2/regexp.cc",
    "chars": 27288,
    "preview": "// Copyright 2006 The RE2 Authors.  All Rights Reserved.\n// Use of this source code is governed by a BSD-style\n// licens"
  },
  {
    "path": "re2/regexp.h",
    "chars": 24342,
    "preview": "// Copyright 2006 The RE2 Authors.  All Rights Reserved.\n// Use of this source code is governed by a BSD-style\n// licens"
  },
  {
    "path": "re2/set.cc",
    "chars": 5082,
    "preview": "// Copyright 2010 The RE2 Authors.  All Rights Reserved.\n// Use of this source code is governed by a BSD-style\n// licens"
  },
  {
    "path": "re2/set.h",
    "chars": 2693,
    "preview": "// Copyright 2010 The RE2 Authors.  All Rights Reserved.\n// Use of this source code is governed by a BSD-style\n// licens"
  },
  {
    "path": "re2/simplify.cc",
    "chars": 21084,
    "preview": "// Copyright 2006 The RE2 Authors.  All Rights Reserved.\n// Use of this source code is governed by a BSD-style\n// licens"
  },
  {
    "path": "re2/sparse_array.h",
    "chars": 11976,
    "preview": "// Copyright 2006 The RE2 Authors.  All Rights Reserved.\n// Use of this source code is governed by a BSD-style\n// licens"
  },
  {
    "path": "re2/sparse_set.h",
    "chars": 7142,
    "preview": "// Copyright 2006 The RE2 Authors.  All Rights Reserved.\n// Use of this source code is governed by a BSD-style\n// licens"
  },
  {
    "path": "re2/stringpiece.h",
    "chars": 504,
    "preview": "// Copyright 2022 The RE2 Authors.  All Rights Reserved.\n// Use of this source code is governed by a BSD-style\n// licens"
  },
  {
    "path": "re2/testing/backtrack.cc",
    "chars": 9372,
    "preview": "// Copyright 2008 The RE2 Authors.  All Rights Reserved.\n// Use of this source code is governed by a BSD-style\n// licens"
  },
  {
    "path": "re2/testing/charclass_test.cc",
    "chars": 5959,
    "preview": "// Copyright 2006 The RE2 Authors.  All Rights Reserved.\n// Use of this source code is governed by a BSD-style\n// licens"
  },
  {
    "path": "re2/testing/compile_test.cc",
    "chars": 12018,
    "preview": "// Copyright 2007 The RE2 Authors.  All Rights Reserved.\n// Use of this source code is governed by a BSD-style\n// licens"
  },
  {
    "path": "re2/testing/dfa_test.cc",
    "chars": 12455,
    "preview": "// Copyright 2006-2008 The RE2 Authors.  All Rights Reserved.\n// Use of this source code is governed by a BSD-style\n// l"
  },
  {
    "path": "re2/testing/dump.cc",
    "chars": 4491,
    "preview": "// Copyright 2006 The RE2 Authors.  All Rights Reserved.\n// Use of this source code is governed by a BSD-style\n// licens"
  },
  {
    "path": "re2/testing/exhaustive1_test.cc",
    "chars": 1298,
    "preview": "// Copyright 2008 The RE2 Authors.  All Rights Reserved.\n// Use of this source code is governed by a BSD-style\n// licens"
  },
  {
    "path": "re2/testing/exhaustive2_test.cc",
    "chars": 2540,
    "preview": "// Copyright 2008 The RE2 Authors.  All Rights Reserved.\n// Use of this source code is governed by a BSD-style\n// licens"
  },
  {
    "path": "re2/testing/exhaustive3_test.cc",
    "chars": 3365,
    "preview": "// Copyright 2008 The RE2 Authors.  All Rights Reserved.\n// Use of this source code is governed by a BSD-style\n// licens"
  },
  {
    "path": "re2/testing/exhaustive_test.cc",
    "chars": 932,
    "preview": "// Copyright 2008 The RE2 Authors.  All Rights Reserved.\n// Use of this source code is governed by a BSD-style\n// licens"
  },
  {
    "path": "re2/testing/exhaustive_tester.cc",
    "chars": 6117,
    "preview": "// Copyright 2008 The RE2 Authors.  All Rights Reserved.\n// Use of this source code is governed by a BSD-style\n// licens"
  },
  {
    "path": "re2/testing/exhaustive_tester.h",
    "chars": 3700,
    "preview": "// Copyright 2009 The RE2 Authors.  All Rights Reserved.\n// Use of this source code is governed by a BSD-style\n// licens"
  },
  {
    "path": "re2/testing/filtered_re2_test.cc",
    "chars": 10327,
    "preview": "// Copyright 2009 The RE2 Authors.  All Rights Reserved.\n// Use of this source code is governed by a BSD-style\n// licens"
  },
  {
    "path": "re2/testing/mimics_pcre_test.cc",
    "chars": 2087,
    "preview": "// Copyright 2008 The RE2 Authors.  All Rights Reserved.\n// Use of this source code is governed by a BSD-style\n// licens"
  },
  {
    "path": "re2/testing/null_walker.cc",
    "chars": 1415,
    "preview": "// Copyright 2009 The RE2 Authors.  All Rights Reserved.\n// Use of this source code is governed by a BSD-style\n// licens"
  },
  {
    "path": "re2/testing/parse_test.cc",
    "chars": 21829,
    "preview": "// Copyright 2006 The RE2 Authors.  All Rights Reserved.\n// Use of this source code is governed by a BSD-style\n// licens"
  },
  {
    "path": "re2/testing/possible_match_test.cc",
    "chars": 9914,
    "preview": "// Copyright 2006-2008 The RE2 Authors.  All Rights Reserved.\n// Use of this source code is governed by a BSD-style\n// l"
  },
  {
    "path": "re2/testing/random_test.cc",
    "chars": 3722,
    "preview": "// Copyright 2008 The RE2 Authors.  All Rights Reserved.\n// Use of this source code is governed by a BSD-style\n// licens"
  },
  {
    "path": "re2/testing/re2_arg_test.cc",
    "chars": 6442,
    "preview": "// Copyright 2005 The RE2 Authors.  All Rights Reserved.\n// Use of this source code is governed by a BSD-style\n// licens"
  },
  {
    "path": "re2/testing/re2_test.cc",
    "chars": 55102,
    "preview": "// -*- coding: utf-8 -*-\n// Copyright 2002-2009 The RE2 Authors.  All Rights Reserved.\n// Use of this source code is gov"
  },
  {
    "path": "re2/testing/regexp_benchmark.cc",
    "chars": 62705,
    "preview": "// Copyright 2006-2008 The RE2 Authors.  All Rights Reserved.\n// Use of this source code is governed by a BSD-style\n// l"
  },
  {
    "path": "re2/testing/regexp_generator.cc",
    "chars": 8757,
    "preview": "// Copyright 2008 The RE2 Authors.  All Rights Reserved.\n// Use of this source code is governed by a BSD-style\n// licens"
  },
  {
    "path": "re2/testing/regexp_generator.h",
    "chars": 2693,
    "preview": "// Copyright 2008 The RE2 Authors.  All Rights Reserved.\n// Use of this source code is governed by a BSD-style\n// licens"
  },
  {
    "path": "re2/testing/regexp_test.cc",
    "chars": 2314,
    "preview": "// Copyright 2006 The RE2 Authors.  All Rights Reserved.\n// Use of this source code is governed by a BSD-style\n// licens"
  },
  {
    "path": "re2/testing/required_prefix_test.cc",
    "chars": 6064,
    "preview": "// Copyright 2009 The RE2 Authors.  All Rights Reserved.\n// Use of this source code is governed by a BSD-style\n// licens"
  },
  {
    "path": "re2/testing/search_test.cc",
    "chars": 8727,
    "preview": "// Copyright 2006-2007 The RE2 Authors.  All Rights Reserved.\n// Use of this source code is governed by a BSD-style\n// l"
  },
  {
    "path": "re2/testing/set_test.cc",
    "chars": 6226,
    "preview": "// Copyright 2010 The RE2 Authors.  All Rights Reserved.\n// Use of this source code is governed by a BSD-style\n// licens"
  },
  {
    "path": "re2/testing/simplify_test.cc",
    "chars": 9164,
    "preview": "// Copyright 2006 The RE2 Authors.  All Rights Reserved.\n// Use of this source code is governed by a BSD-style\n// licens"
  },
  {
    "path": "re2/testing/string_generator.cc",
    "chars": 3760,
    "preview": "// Copyright 2008 The RE2 Authors.  All Rights Reserved.\n// Use of this source code is governed by a BSD-style\n// licens"
  },
  {
    "path": "re2/testing/string_generator.h",
    "chars": 2770,
    "preview": "// Copyright 2008 The RE2 Authors.  All Rights Reserved.\n// Use of this source code is governed by a BSD-style\n// licens"
  },
  {
    "path": "re2/testing/string_generator_test.cc",
    "chars": 2719,
    "preview": "// Copyright 2008 The RE2 Authors.  All Rights Reserved.\n// Use of this source code is governed by a BSD-style\n// licens"
  },
  {
    "path": "re2/testing/tester.cc",
    "chars": 20898,
    "preview": "// Copyright 2008 The RE2 Authors.  All Rights Reserved.\n// Use of this source code is governed by a BSD-style\n// licens"
  },
  {
    "path": "re2/testing/tester.h",
    "chars": 4074,
    "preview": "// Copyright 2008 The RE2 Authors.  All Rights Reserved.\n// Use of this source code is governed by a BSD-style\n// licens"
  },
  {
    "path": "re2/tostring.cc",
    "chars": 8746,
    "preview": "// Copyright 2006 The RE2 Authors.  All Rights Reserved.\n// Use of this source code is governed by a BSD-style\n// licens"
  },
  {
    "path": "re2/unicode.py",
    "chars": 7746,
    "preview": "# Copyright 2008 The RE2 Authors.  All Rights Reserved.\n# Use of this source code is governed by a BSD-style\n# license t"
  },
  {
    "path": "re2/unicode_casefold.cc",
    "chars": 13769,
    "preview": "\n// GENERATED BY make_unicode_casefold.py; DO NOT EDIT.\n// make_unicode_casefold.py >unicode_casefold.cc\n\n#include \"re2/"
  },
  {
    "path": "re2/unicode_casefold.h",
    "chars": 2535,
    "preview": "// Copyright 2008 The RE2 Authors.  All Rights Reserved.\n// Use of this source code is governed by a BSD-style\n// licens"
  },
  {
    "path": "re2/unicode_groups.cc",
    "chars": 126675,
    "preview": "\n// GENERATED BY make_unicode_groups.py; DO NOT EDIT.\n// make_unicode_groups.py >unicode_groups.cc\n\n#include \"re2/unicod"
  },
  {
    "path": "re2/unicode_groups.h",
    "chars": 1525,
    "preview": "// Copyright 2008 The RE2 Authors.  All Rights Reserved.\n// Use of this source code is governed by a BSD-style\n// licens"
  },
  {
    "path": "re2/walker-inl.h",
    "chars": 7841,
    "preview": "// Copyright 2006 The RE2 Authors.  All Rights Reserved.\n// Use of this source code is governed by a BSD-style\n// licens"
  },
  {
    "path": "re2.pc.in",
    "chars": 275,
    "preview": "includedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@\nlibdir=@CMAKE_INSTALL_FULL_LIBDIR@\n\nName: re2\nDescription: RE2 is a fast, saf"
  },
  {
    "path": "re2Config.cmake.in",
    "chars": 531,
    "preview": "# Copyright 2022 The RE2 Authors.  All Rights Reserved.\n# Use of this source code is governed by a BSD-style\n# license t"
  },
  {
    "path": "runtests",
    "chars": 646,
    "preview": "#!/usr/bin/env sh\n\n# System Integrity Protection on Darwin complicated these matters somewhat.\n# See https://github.com/"
  },
  {
    "path": "testinstall.cc",
    "chars": 621,
    "preview": "// Copyright 2008 The RE2 Authors.  All Rights Reserved.\n// Use of this source code is governed by a BSD-style\n// licens"
  },
  {
    "path": "ucs2.diff",
    "chars": 19201,
    "preview": "This is a dump from Google's source control system of the change\nthat removed UCS-2 support from RE2.  As the explanatio"
  },
  {
    "path": "util/malloc_counter.h",
    "chars": 505,
    "preview": "// Copyright 2009 The RE2 Authors.  All Rights Reserved.\n// Use of this source code is governed by a BSD-style\n// licens"
  },
  {
    "path": "util/pcre.cc",
    "chars": 33126,
    "preview": "// Copyright 2003-2009 Google Inc.  All rights reserved.\n// Use of this source code is governed by a BSD-style\n// licens"
  },
  {
    "path": "util/pcre.h",
    "chars": 27687,
    "preview": "// Copyright 2003-2010 Google Inc.  All Rights Reserved.\n// Use of this source code is governed by a BSD-style\n// licens"
  },
  {
    "path": "util/rune.cc",
    "chars": 4941,
    "preview": "/*\n * The authors of this software are Rob Pike and Ken Thompson.\n *              Copyright (c) 2002 by Lucent Technolog"
  },
  {
    "path": "util/strutil.cc",
    "chars": 791,
    "preview": "// Copyright 1999-2005 The RE2 Authors.  All Rights Reserved.\n// Use of this source code is governed by a BSD-style\n// l"
  },
  {
    "path": "util/strutil.h",
    "chars": 339,
    "preview": "// Copyright 2016 The RE2 Authors.  All Rights Reserved.\n// Use of this source code is governed by a BSD-style\n// licens"
  },
  {
    "path": "util/utf.h",
    "chars": 1516,
    "preview": "/*\n * The authors of this software are Rob Pike and Ken Thompson.\n *              Copyright (c) 2002 by Lucent Technolog"
  }
]

About this extraction

This page contains the full source code of the google/re2 GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 134 files (1.3 MB), approximately 425.0k tokens, and a symbol index with 942 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!